├── .gitignore ├── LICENSE ├── README.md ├── history ├── E0001.md ├── E0002.md ├── E0003.md └── E0398.md ├── new ├── E0564.md └── E0594.md └── now ├── E0004.md ├── E0005.md ├── E0007.md ├── E0008.md ├── E0009.md ├── E0053.md ├── E0088.md ├── E0090.md ├── E0106.md ├── E0110.md ├── E0161.md ├── E0195.md ├── E0207.md ├── E0261.md ├── E0262.md ├── E0263.md ├── E0277.md ├── E0303.md ├── E0309.md ├── E0310.md ├── E0312.md ├── E0382.md ├── E0392.md ├── E0478.md ├── E0491.md ├── E0496.md ├── E0505.md ├── E0509.md ├── E0581.md ├── E0582.md ├── E0597.md ├── E0621.md └── E0622.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [官方Error索引页面](https://doc.rust-lang.org/error-index.html) 2 | 3 | # 说明 4 | 5 | - 「镜子照出身体,错误反映灵魂」 6 | - 「最好的好人,都是犯过错误的过来人」 7 | 8 | Rust Compiler Error 中文翻译项目,方便查阅,欢迎贡献。 9 | 10 | - now目录为当前编译器还存在的错误代码 11 | - new目录为当前编译期存在的错误代码,但是在官方Error索引页面中不存在的代码解释 12 | - history目录为当前编译器不再发出的错误代码,但有些已经改为了warning 13 | 14 | ## 如何贡献: 15 | 16 | - 请自己先测试一遍文档中的错误代码是否符合描述 17 | - 保留英文原文描述,中文翻译置于下方 18 | - 选择本项目目录中没有包含的错误码进行翻译 19 | - 描述中如果有原链接的要保留原链接 20 | 21 | ### 交流 22 | 23 | 贡献者欢迎加入扣群交流:244351570 24 | -------------------------------------------------------------------------------- /history/E0001.md: -------------------------------------------------------------------------------- 1 | # E0001 2 | 3 | --- 4 | 5 | Note: this error code is no longer emitted by the compiler. 6 | 7 | This error suggests that the expression arm corresponding to the noted pattern will never be reached as for all possible values of the expression being matched, one of the preceding patterns will match. 8 | 9 | This means that perhaps some of the preceding patterns are too general, this one is too specific or the ordering is incorrect. 10 | 11 | For example, the following match block has too many arms: 12 | 13 | ```rust 14 | match Some(0) { 15 | Some(bar) => {/* ... */} 16 | x => {/* ... */} // This handles the `None` case 17 | _ => {/* ... */} // All possible cases have already been handled 18 | } 19 | ``` 20 | 21 | match blocks have their patterns matched in order, so, for example, putting a wildcard arm above a more specific arm will make the latter arm irrelevant. 22 | 23 | Ensure the ordering of the match arm is correct and remove any superfluous arms. 24 | 25 | # E0001 26 | 27 | --- 28 | 29 | 注意:编译器已经不再发出此错误码。但依然会发出Warning: unreachable pattern 30 | 31 | 该错误表明,表达式分支将永远不会和表达式所能匹配的所有可能值相对应,靠前的分支会将会优先匹配。 32 | 33 | 当前面的分支模式太笼统,不够具体或者分支顺序错误的情况下会发生这种错误。 34 | 35 | 例如,下面的match块就包含多余的分支。 36 | 37 | ```rust 38 | match Some(0) { 39 | Some(bar) => {/* ... */} 40 | x => {/* ... */} // 这是处理None的情况 41 | _ => {/* ... */} // 所有的情况已经被上面的分支都匹配过了 42 | } 43 | ``` 44 | 45 | 运行该段代码,会发出Warning: unreachable pattern 46 | 47 | match块按分支顺序进行匹配,所以,对于此例,前面的分支都覆盖了具体的情况,最后的分支就变的无关紧要了。使用它的时候要确保匹配分支的顺序正确,识别并移除多余的匹配分支。 48 | -------------------------------------------------------------------------------- /history/E0002.md: -------------------------------------------------------------------------------- 1 | # E0002 2 | 3 | --- 4 | 5 | Note: this error code is no longer emitted by the compiler. 6 | 7 | This error indicates that an empty match expression is invalid because the type it is matching on is non-empty (there exist values of this type). In safe code it is impossible to create an instance of an empty type, so empty match expressions are almost never desired. This error is typically fixed by adding one or more cases to the match expression. 8 | 9 | An example of an empty type is enum Empty { }. So, the following will work: 10 | 11 | ```rust 12 | enum Empty {} 13 | 14 | fn foo(x: Empty) { 15 | match x { 16 | // empty 17 | } 18 | } 19 | ``` 20 | 21 | However, this won't: 22 | 23 | ``` 24 | fn foo(x: Option) { 25 | match x { 26 | // empty 27 | } 28 | } 29 | ``` 30 | 31 | # E0002 32 | 33 | --- 34 | 35 | 注意:编译器已经不再发出此错误码。 36 | 37 | 该错误表示空的match表达式是无效的,因为它匹配的类型不为空,该类型有值。安全的代码是不允许创建一个空类型的实例,所以根本不需要空match表达式。可以增加一个或多个匹配分支来修复此错误。 38 | 39 | 下面代码是空类型`enum Empty {}` 的示例,它将会正常编译: 40 | 41 | ```rust 42 | enum Empty {} 43 | 44 | fn foo(x: Empty) { 45 | match x { 46 | // empty 47 | } 48 | } 49 | ``` 50 | 51 | 然而,下面的代码则会报错: 52 | 53 | ``` 54 | fn foo(x: Option) { 55 | match x { 56 | // empty 57 | } 58 | } 59 | ``` 60 | 61 | 但此代码错误信息为: 62 | 63 | ```rust 64 | error[E0004]: non-exhaustive patterns: type std::option::Option is non-empty 65 | ``` -------------------------------------------------------------------------------- /history/E0003.md: -------------------------------------------------------------------------------- 1 | # E0003 2 | 3 | --- 4 | 5 | Note: this error code is no longer emitted by the compiler. 6 | 7 | Not-a-Number (NaN) values cannot be compared for equality and hence can never match the input to a match expression. So, the following will not compile: 8 | 9 | ```rust 10 | const NAN: f32 = 0.0 / 0.0; 11 | 12 | let number = 0.1f32; 13 | 14 | match number { 15 | NAN => { /* ... */ }, 16 | _ => {} 17 | } 18 | ``` 19 | 20 | To match against NaN values, you should instead use the is_nan() method in a guard, like so: 21 | 22 | ```rust 23 | 24 | let number = 0.1f32; 25 | 26 | match number { 27 | x if x.is_nan() => { /* ... */ } 28 | _ => {} 29 | } 30 | ``` 31 | 32 | # E0003 33 | 34 | --- 35 | 36 | 注意:编译器已经不再发出此错误码。 37 | 38 | 非数字值(NaN)不能进行相等比较,因此其永远不能作为match表达式的匹配输入。所以下面的代码将不会通过编译: 39 | 40 | ```rust 41 | const NAN: f32 = 0.0 / 0.0; 42 | 43 | let number = 0.1f32; 44 | 45 | match number { 46 | NAN => { /* ... */ }, // error: floating point constants cannot be used in patterns 47 | _ => {} 48 | } 49 | ``` 50 | 51 | 为了防止NaN值,应该在match分支中使用is_nan()方法作为match guard条件,就像这样: 52 | 53 | ```rust 54 | 55 | let number = 0.1f32; 56 | 57 | match number { 58 | x if x.is_nan() => { /* ... */ } 59 | _ => {} 60 | } 61 | ``` -------------------------------------------------------------------------------- /history/E0398.md: -------------------------------------------------------------------------------- 1 | # E0398 2 | 3 | --- 4 | 5 | Note: this error code is no longer emitted by the compiler. 6 | 7 | 8 | In Rust 1.3, the default object lifetime bounds are expected to change, as described in [RFC 1156](https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md). You are getting a warning because the compiler thinks it is possible that this change will cause a compilation error in your code. It is possible, though unlikely, that this is a false alarm. 9 | 10 | The heart of the change is that where &'a Box used to default to &'a Box, it now defaults to &'a Box (here, SomeTrait is the name of some trait type). Note that the only types which are affected are references to boxes, like &Box or &[Box]. More common types like &SomeTrait or Box are unaffected. 11 | 12 | To silence this warning, edit your code to use an explicit bound. Most of the time, this means that you will want to change the signature of a function that you are calling. For example, if the error is reported on a call like foo(x), and foo is defined as follows: 13 | 14 | ```rust 15 | fn foo(arg: &Box) { /* ... */ } 16 | ``` 17 | 18 | You might change it to: 19 | 20 | ```rust 21 | fn foo<'a>(arg: &'a Box) { /* ... */ } 22 | ``` 23 | 24 | This explicitly states that you expect the trait object SomeTrait to contain references (with a maximum lifetime of 'a). 25 | 26 | # E0398 27 | 28 | --- 29 | 30 | 注意:编译器已经不再发出此错误码。 31 | 32 | 在Rust1.3 ,默认对象生命周期限定期望改变,如[RFC 1156](https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md)。你会得到一个警告,因为编译器认为这种改变可能会导致代码中的编译错误。尽管不太可能,但只是警告。 33 | 34 | 35 | 这次变化的核心在于,&'a Box默认被用于&'a Box,现在默认是&'a Box(SomeTrait是某些trait的名称)。请注意,唯一受影响的是对Box类型的引用,像&Box 或 &[Box]。更多场景的类型不受影响,比如&SomeTrait 或 Box。 36 | 37 | 显式的指定生命周期限定可以消除上述警告。 大多数情况下,这意味着要更改正在调用的函数的签名。 例如,如果foo(x)这样的调用中报告错误,并且foo定义如下: 38 | 39 | 40 | ```rust 41 | fn foo(arg: &Box) { /* ... */ } 42 | ``` 43 | 44 | 可以改为: 45 | 46 | ```rust 47 | fn foo<'a>(arg: &'a Box) { /* ... */ } 48 | ``` 49 | 50 | 这明确表示你想让trait对象SomeTrait包括一个引用(最长生命周期是'a)。 51 | -------------------------------------------------------------------------------- /new/E0564.md: -------------------------------------------------------------------------------- 1 | # E0564 2 | 3 | --- 4 | 5 | 此错误并未更新到官方错误列表索引页面中。 6 | 7 | 该错误表示,在impl Trait中必须使用生命周期参数,但是现在闭包里出现了借用 &u8。 8 | 9 | 10 | 11 | ```rust 12 | #![feature(conservative_impl_trait)] 13 | fn three_sum(c: u8) -> impl FnOnce(u8, u8) -> u8 { 14 | // error[E0564]: only named lifetimes are allowed in `impl Trait`, but `` was found in the type `[closure@src/main.rs:3:6: 3:22 c:&u8] 15 | |a, b| a + b + c 16 | } 17 | fn main() { 18 | let sum_from_basic_value = three_sum(1); 19 | assert_eq!(6, sum_from_basic_value(2, 3)); 20 | } 21 | ``` 22 | 23 | 要修正也简单,使用move关键字将闭包捕获的变量所有权转移到闭包内。 24 | 25 | ```rust 26 | #![feature(conservative_impl_trait)] 27 | fn three_sum(c: u8) -> impl FnOnce(u8, u8) -> u8 { 28 | move |a, b| a + b + c 29 | } 30 | fn main() { 31 | let sum_from_basic_value = three_sum(1); 32 | assert_eq!(6, sum_from_basic_value(2, 3)); 33 | } 34 | ``` -------------------------------------------------------------------------------- /new/E0594.md: -------------------------------------------------------------------------------- 1 | # E0594 2 | --- 3 | 4 | 该错误表示不能为不可变借用指派新值。 5 | 6 | 7 | 出错代码示例: 8 | 9 | ```rust 10 | fn main() { 11 | let mut num = 5; 12 | let r1 = &num as *const i32; 13 | let r2 = &mut num as *mut i32; 14 | 15 | unsafe { 16 | *r1 = 6; 17 | // ^ error[E0594]: cannot assign to immutable dereference of raw pointer `*r1` 18 | println!("r1 is: {}", *r1); 19 | println!("r2 is: {}", *r2); 20 | } 21 | } 22 | ``` 23 | 24 | or 25 | 26 | ```rust 27 | static NUM: i32 = 18; 28 | 29 | fn main() { 30 | NUM = 20; //[ast]~ ERROR E0594 31 | //[mir]~^ ERROR cannot assign to immutable item `NUM` 32 | 33 | ``` 34 | -------------------------------------------------------------------------------- /now/E0004.md: -------------------------------------------------------------------------------- 1 | # E0004 2 | 3 | --- 4 | 5 | This error indicates that the compiler cannot guarantee a matching pattern for one or more possible inputs to a match expression. Guaranteed matches are required in order to assign values to match expressions, or alternatively, determine the flow of execution. Erroneous code example: 6 | 7 | ```rust 8 | enum Terminator { 9 | HastaLaVistaBaby, 10 | TalkToMyHand, 11 | } 12 | 13 | let x = Terminator::HastaLaVistaBaby; 14 | 15 | match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered 16 | Terminator::TalkToMyHand => {} 17 | } 18 | ``` 19 | 20 | If you encounter this error you must alter your patterns so that every possible value of the input type is matched. For types with a small number of variants (like enums) you should probably cover all cases explicitly. Alternatively, the underscore _ wildcard pattern can be added after all other patterns to match "anything else". Example: 21 | 22 | ```rust 23 | enum Terminator { 24 | HastaLaVistaBaby, 25 | TalkToMyHand, 26 | } 27 | 28 | let x = Terminator::HastaLaVistaBaby; 29 | 30 | match x { 31 | Terminator::TalkToMyHand => {} 32 | Terminator::HastaLaVistaBaby => {} 33 | } 34 | 35 | // or: 36 | 37 | match x { 38 | Terminator::TalkToMyHand => {} 39 | _ => {} 40 | } 41 | ``` 42 | 43 | # E0004 44 | 45 | --- 46 | 47 | 该错误表示,编译器无法保证match表达式中的模式和可能的输入互相匹配。只有确定的匹配才能为match表达式分配值,或者选择确定的执行流程。 错误的代码示例如下: 48 | 49 | ```rust 50 | enum Terminator { 51 | HastaLaVistaBaby, 52 | TalkToMyHand, 53 | } 54 | 55 | let x = Terminator::HastaLaVistaBaby; 56 | 57 | match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered 58 | Terminator::TalkToMyHand => {} 59 | } 60 | ``` 61 | 62 | 如果遇到此错误,你必须修改模式以便于输入类型的每个可能的值都能被匹配。对于拥有少量变体(variant,比如enum)的类型,需要显式地覆盖所有的情况。或者使用下划线通配符`_`作为最后的模式来匹配所有其他的可能。比如: 63 | 64 | 65 | ```rust 66 | enum Terminator { 67 | HastaLaVistaBaby, 68 | TalkToMyHand, 69 | } 70 | 71 | let x = Terminator::HastaLaVistaBaby; 72 | 73 | match x { 74 | Terminator::TalkToMyHand => {} 75 | Terminator::HastaLaVistaBaby => {} 76 | } 77 | 78 | // or: 79 | 80 | match x { 81 | Terminator::TalkToMyHand => {} 82 | _ => {} 83 | } 84 | ``` 85 | -------------------------------------------------------------------------------- /now/E0005.md: -------------------------------------------------------------------------------- 1 | # E0005 2 | 3 | --- 4 | Patterns used to bind names must be irrefutable, that is, they must guarantee that a name will be extracted in all cases. Erroneous code example: 5 | 6 | 7 | ```rust 8 | let x = Some(1); 9 | let Some(y) = x; 10 | // error: refutable pattern in local binding: `None` not covered 11 | ``` 12 | 13 | If you encounter this error you probably need to use a match or if let to deal with the possibility of failure. Example: 14 | 15 | 16 | ```rust 17 | 18 | let x = Some(1); 19 | 20 | match x { 21 | Some(y) => { 22 | // do something 23 | }, 24 | None => {} 25 | } 26 | 27 | // or: 28 | 29 | if let Some(y) = x { 30 | // do something 31 | } 32 | ``` 33 | 34 | # E0005 35 | 36 | --- 37 | 用于绑定的模式必须是确定的,不能包含歧义。也就是说,它们必须保证在所有的情况下都能以唯一的名称被匹配。下面是错误示例: 38 | 39 | ```rust 40 | let x = Some(1); 41 | let Some(y) = x; 42 | // error: 该本地绑定包含二义性: `None` 的情况并未覆盖 43 | // 如果x的值为None,那么标识符y没有对应的数据可绑定(此时y类似于野指针) 44 | // 也就无法保证y在任何时候都能正常访问 45 | ``` 46 | 47 | 如果你遇到了这个错误,你可能需要使用`match`(控制流运算符)或`if let`语句来处理可能遇到的出错情况。例如: 48 | 49 | ```rust 50 | 51 | let x = Some(1); 52 | 53 | match x { 54 | Some(y) => { 55 | // do something 56 | }, 57 | None => {} 58 | } 59 | 60 | // or: 61 | 62 | if let Some(y) = x { 63 | // do something 64 | } 65 | ``` 66 | -------------------------------------------------------------------------------- /now/E0007.md: -------------------------------------------------------------------------------- 1 | # E0007 2 | 3 | --- 4 | 5 | This error indicates that the bindings in a match arm would require a value to be moved into more than one location, thus violating unique ownership. Code like the following is invalid as it requires the entire Option to be moved into a variable called op_string while simultaneously requiring the inner String to be moved into a variable called s. 6 | 7 | 8 | ```rust 9 | let x = Some("s".to_string()); 10 | 11 | match x { 12 | op_string @ Some(s) => {}, // error: cannot bind by-move with sub-bindings 13 | None => {}, 14 | } 15 | ``` 16 | 17 | See also the error E0303. 18 | 19 | 20 | # E0007 21 | 22 | --- 23 | 24 | 此错误表示匹配中的绑定将需要将值move到多个位置,从而违反唯一所有权。 像下面这样的代码是无效的,因为它需要将整个Option move到一个名为op_string的变量中,同时要求将内部String移动到变量s中。 25 | 26 | 27 | ```rust 28 | let x = Some("s".to_string()); 29 | 30 | match x { 31 | op_string @ Some(s) => {}, // error: cannot bind by-move with sub-bindings 32 | None => {}, 33 | } 34 | ``` 35 | 36 | 另请参见错误E0303。 37 | 38 | -------------------------------------------------------------------------------- /now/E0008.md: -------------------------------------------------------------------------------- 1 | # E0008 2 | 3 | --- 4 | 5 | Names bound in match arms retain their type in pattern guards. As such, if a name is bound by move in a pattern, it should also be moved to wherever it is referenced in the pattern guard code. Doing so however would prevent the name from being available in the body of the match arm. Consider the following: 6 | 7 | ```rust 8 | match Some("hi".to_string()) { 9 | Some(s) if s.len() == 0 => {}, // use s. 10 | _ => {}, 11 | } 12 | ``` 13 | 14 | The variable s has type String, and its use in the guard is as a variable of type String. The guard code effectively executes in a separate scope to the body of the arm, so the value would be moved into this anonymous scope and therefore becomes unavailable in the body of the arm. 15 | 16 | The problem above can be solved by using the ref keyword. 17 | 18 | ```rust 19 | match Some("hi".to_string()) { 20 | Some(ref s) if s.len() == 0 => {}, 21 | _ => {}, 22 | } 23 | ``` 24 | 25 | Though this example seems innocuous and easy to solve, the problem becomes clear when it encounters functions which consume the value: 26 | 27 | ```rust 28 | struct A{} 29 | 30 | impl A { 31 | fn consume(self) -> usize { 32 | 0 33 | } 34 | } 35 | 36 | fn main() { 37 | let a = Some(A{}); 38 | match a { 39 | Some(y) if y.consume() > 0 => {} 40 | _ => {} 41 | } 42 | } 43 | ``` 44 | 45 | In this situation, even the ref keyword cannot solve it, since borrowed content cannot be moved. This problem cannot be solved generally. If the value can be cloned, here is a not-so-specific solution: 46 | 47 | ```rust 48 | 49 | #[derive(Clone)] 50 | struct A{} 51 | 52 | impl A { 53 | fn consume(self) -> usize { 54 | 0 55 | } 56 | } 57 | 58 | fn main() { 59 | let a = Some(A{}); 60 | match a{ 61 | Some(ref y) if y.clone().consume() > 0 => {} 62 | _ => {} 63 | } 64 | } 65 | ``` 66 | 67 | If the value will be consumed in the pattern guard, using its clone will not move its ownership, so the code works. 68 | 69 | # E0008 70 | 71 | --- 72 | 73 | 在match匹配分支中的绑定持有模式守卫(guard)中的类型。因此,如果一个绑定转移到模式中,它也应该被转移到模式守卫中使用它的那个位置。否则会阻止该名称在匹配分支的执行块中使用。考虑下列代码: 74 | 75 | 76 | ```rust 77 | match Some("hi".to_string()) { 78 | Some(s) if s.len() == 0 => {}, // error[E0008]: cannot bind by-move into a pattern guard 79 | _ => {}, 80 | } 81 | ``` 82 | 83 | 变量s为String类型,它也被当作String类型的变量用于模式守卫中。守卫代码是在匹配分支的独立作用域执行的,所以该值会被移动到这个匿名作用域中,因此在匹配分支的执行体中将不再可用。 84 | 85 | 可以通过ref关键字解决此问题. 86 | 87 | ```rust 88 | match Some("hi".to_string()) { 89 | Some(ref s) if s.len() == 0 => {}, 90 | _ => {}, 91 | } 92 | ``` 93 | 94 | 虽然这个示例看似无害,并且很容易处理,但是当它遇到消费该值的函数问题就会更清晰: 95 | 96 | ```rust 97 | struct A{} 98 | 99 | impl A { 100 | fn consume(self) -> usize { 101 | 0 102 | } 103 | } 104 | 105 | fn main() { 106 | let a = Some(A{}); 107 | match a { 108 | Some(y) if y.consume() > 0 => {} 109 | _ => {} 110 | } 111 | } 112 | ``` 113 | 114 | 在这种情况下,即使ref关键字也无法解决,因为借用的内容不能移动。 这个问题一般不能解决。 如果可以克隆该值,这里是一个粗略的解决方案。 115 | 116 | 117 | ```rust 118 | 119 | #[derive(Clone)] 120 | struct A{} 121 | 122 | impl A { 123 | fn consume(self) -> usize { 124 | 0 125 | } 126 | } 127 | 128 | fn main() { 129 | let a = Some(A{}); 130 | match a{ 131 | Some(ref y) if y.clone().consume() > 0 => {} 132 | _ => {} 133 | } 134 | } 135 | ``` 136 | 137 | 如果该值将在模式守卫中使用,则使用其克隆将不会移动其所有权,因此代码可以正常工作。 -------------------------------------------------------------------------------- /now/E0009.md: -------------------------------------------------------------------------------- 1 | # E0009 2 | 3 | --- 4 | 5 | In a pattern, all values that don't implement the Copy trait have to be bound the same way. The goal here is to avoid binding simultaneously by-move and by-ref. 6 | 7 | This limitation may be removed in a future version of Rust. 8 | 9 | Erroneous code example: 10 | 11 | ```rust 12 | 13 | struct X { x: (), } 14 | 15 | let x = Some((X { x: () }, X { x: () })); 16 | match x { 17 | Some((y, ref z)) => {}, // error: cannot bind by-move and by-ref in the 18 | // same pattern 19 | None => panic!() 20 | } 21 | ``` 22 | 23 | You have two solutions: 24 | 25 | Solution #1: Bind the pattern's values the same way. 26 | 27 | ```rust 28 | struct X { x: (), } 29 | 30 | let x = Some((X { x: () }, X { x: () })); 31 | match x { 32 | Some((ref y, ref z)) => {}, 33 | // or Some((y, z)) => {} 34 | None => panic!() 35 | } 36 | 37 | ``` 38 | 39 | Solution #2: Implement the Copy trait for the X structure. 40 | 41 | However, please keep in mind that the first solution should be preferred. 42 | 43 | ```rust 44 | #[derive(Clone, Copy)] 45 | struct X { x: (), } 46 | 47 | let x = Some((X { x: () }, X { x: () })); 48 | match x { 49 | Some((y, ref z)) => {}, 50 | None => panic!() 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /now/E0053.md: -------------------------------------------------------------------------------- 1 | # E0053 2 | 3 | --- 4 | 5 | The parameters of any trait method must match between a trait implementation and the trait definition. 6 | 7 | Here are a couple examples of this error: 8 | 9 | ```rust 10 | 11 | trait Foo { 12 | fn foo(x: u16); 13 | fn bar(&self); 14 | } 15 | 16 | struct Bar; 17 | 18 | impl Foo for Bar { 19 | // error, expected u16, found i16 20 | fn foo(x: i16) { } 21 | 22 | // error, types differ in mutability 23 | fn bar(&mut self) { } 24 | } 25 | ``` 26 | 27 | # E0053 28 | 29 | --- 30 | 31 | 任何trait方法的参数必须要与该trait的定义和实现相匹配。 32 | 33 | 以下是几个错误示例: 34 | 35 | 36 | ```rust 37 | 38 | trait Foo { 39 | fn foo(x: u16); 40 | fn bar(&self); 41 | } 42 | 43 | struct Bar; 44 | 45 | impl Foo for Bar { 46 | // error, 期望 u16, 发现 i16 47 | fn foo(x: i16) { } 48 | 49 | // error, 类型的可变性不同 50 | fn bar(&mut self) { } 51 | } 52 | ``` -------------------------------------------------------------------------------- /now/E0088.md: -------------------------------------------------------------------------------- 1 | # E0088 2 | 3 | --- 4 | 5 | You gave too many lifetime parameters. Erroneous code example: 6 | 7 | ```rust 8 | 9 | fn f() {} 10 | 11 | fn main() { 12 | f::<'static>() // error: too many lifetime parameters provided 13 | } 14 | ``` 15 | 16 | Please check you give the right number of lifetime parameters. Example: 17 | 18 | ```rust 19 | fn f() {} 20 | 21 | fn main() { 22 | f() // ok! 23 | } 24 | ``` 25 | 26 | It's also important to note that the Rust compiler can generally determine the lifetime by itself. Example: 27 | 28 | ```rust 29 | 30 | struct Foo { 31 | value: String 32 | } 33 | 34 | impl Foo { 35 | // it can be written like this 36 | fn get_value<'a>(&'a self) -> &'a str { &self.value } 37 | // but the compiler works fine with this too: 38 | fn without_lifetime(&self) -> &str { &self.value } 39 | } 40 | 41 | fn main() { 42 | let f = Foo { value: "hello".to_owned() }; 43 | 44 | println!("{}", f.get_value()); 45 | println!("{}", f.without_lifetime()); 46 | } 47 | ``` 48 | 49 | # E0088 50 | 51 | --- 52 | 53 | 你给了太多的生命周期参数。错误代码如下: 54 | 55 | 56 | ```rust 57 | 58 | fn f() {} 59 | 60 | fn main() { 61 | f::<'static>() // error: 提供了太多的生命周期参数 62 | } 63 | ``` 64 | 65 | 检查并确保给出正确的生命周期参数个数. 例如: 66 | 67 | ```rust 68 | fn f() {} 69 | 70 | fn main() { 71 | f() // ok! 72 | } 73 | ``` 74 | 75 | 76 | 值得注意的是,Rust编译器可以自己决定使用生命周期。比如: 77 | 78 | ```rust 79 | 80 | struct Foo { 81 | value: String 82 | } 83 | 84 | impl Foo { 85 | // 可以这么写 86 | fn get_value<'a>(&'a self) -> &'a str { &self.value } 87 | // 但是这样写也可以工作,编译器会自动补全生命周期参数 88 | fn without_lifetime(&self) -> &str { &self.value } 89 | } 90 | 91 | fn main() { 92 | let f = Foo { value: "hello".to_owned() }; 93 | 94 | println!("{}", f.get_value()); 95 | println!("{}", f.without_lifetime()); 96 | } 97 | ``` 98 | -------------------------------------------------------------------------------- /now/E0090.md: -------------------------------------------------------------------------------- 1 | # E0090 2 | 3 | --- 4 | 5 | You gave too few lifetime parameters. Example: 6 | 7 | ```rust 8 | fn foo<'a: 'b, 'b: 'a>() {} 9 | 10 | fn main() { 11 | foo::<'static>(); // error, expected 2 lifetime parameters 12 | } 13 | ``` 14 | 15 | Please check you give the right number of lifetime parameters. Example: 16 | 17 | ```rust 18 | fn foo<'a: 'b, 'b: 'a>() {} 19 | 20 | fn main() { 21 | foo::<'static, 'static>(); 22 | } 23 | ``` 24 | 25 | # E0090 26 | 27 | --- 28 | 29 | 生命周期参数太少,比如: 30 | 31 | ```rust 32 | fn foo<'a: 'b, 'b: 'a>() {} 33 | 34 | fn main() { 35 | foo::<'static>(); // 错误,期待两个生命周期参数 36 | } 37 | ``` 38 | 39 | 检查并给定正确的生命周期参数个数,比如: 40 | 41 | ```rust 42 | fn foo<'a: 'b, 'b: 'a>() {} 43 | 44 | fn main() { 45 | foo::<'static, 'static>(); 46 | } 47 | ``` -------------------------------------------------------------------------------- /now/E0106.md: -------------------------------------------------------------------------------- 1 | # E0106 2 | 3 | --- 4 | 5 | This error indicates that a lifetime is missing from a type. If it is an error inside a function signature, the problem may be with failing to adhere to the lifetime elision rules (see below). 6 | 7 | Here are some simple examples of where you'll run into this error: 8 | 9 | ```rust 10 | 11 | struct Foo { x: &bool } // error 12 | struct Foo<'a> { x: &'a bool } // correct 13 | 14 | enum Bar { A(u8), B(&bool), } // error 15 | enum Bar<'a> { A(u8), B(&'a bool), } // correct 16 | 17 | type MyStr = &str; // error 18 | type MyStr<'a> = &'a str; // correct 19 | ``` 20 | 21 | Lifetime elision is a special, limited kind of inference for lifetimes in function signatures which allows you to leave out lifetimes in certain cases. For more background on lifetime elision see [the book](https://doc.rust-lang.org/nightly/book/first-edition/lifetimes.html#lifetime-elision). 22 | 23 | The lifetime elision rules require that any function signature with an elided output lifetime must either have 24 | 25 | - exactly one input lifetime 26 | - or, multiple input lifetimes, but the function must also be a method with a &self or &mut self receiver 27 | 28 | In the first case, the output lifetime is inferred to be the same as the unique input lifetime. In the second case, the lifetime is instead inferred to be the same as the lifetime on &self or &mut self. 29 | 30 | Here are some examples of elision errors: 31 | 32 | ```rust 33 | 34 | // error, no input lifetimes 35 | fn foo() -> &str { } 36 | 37 | // error, `x` and `y` have distinct lifetimes inferred 38 | fn bar(x: &str, y: &str) -> &str { } 39 | 40 | // error, `y`'s lifetime is inferred to be distinct from `x`'s 41 | fn baz<'a>(x: &'a str, y: &str) -> &str { } 42 | ``` 43 | 44 | Here's an example that is currently an error, but may work in a future version of Rust: 45 | 46 | ```rust 47 | struct Foo<'a>(&'a str); 48 | 49 | trait Quux { } 50 | impl Quux for Foo { } 51 | ``` 52 | 53 | Lifetime elision in implementation headers was part of the lifetime elision RFC. It is, however, [currently unimplemented](https://github.com/rust-lang/rust/issues/15872). 54 | 55 | 56 | # E0106 57 | 58 | --- 59 | 60 | 此错误表示类型中确实生命周期。如果是函数签名内的错误,则可能是因为未遵循生命周期省略规则引起的问题(见下文)。 61 | 62 | 下面是一些简单的示例: 63 | 64 | 65 | ```rust 66 | 67 | struct Foo { x: &bool } // 错误 68 | struct Foo<'a> { x: &'a bool } // 正确 69 | 70 | enum Bar { A(u8), B(&bool), } // 错误 71 | enum Bar<'a> { A(u8), B(&'a bool), } // 正确 72 | 73 | type MyStr = &str; // 错误 74 | type MyStr<'a> = &'a str; // 正确 75 | ``` 76 | 77 | 生命周期省略用于推断函数签名中的生命周期,这种推断是特殊并有限制的,它允许你在某些情况下可以不再使用生命周期(参数)。关于生命周期省略的更多背景可以参阅[the book](https://doc.rust-lang.org/nightly/book/first-edition/lifetimes.html#lifetime-elision). 78 | 79 | 生命周期省略规则需要任何省略输出生命周期参数的函数签名必须满足下面两个条件之一: 80 | 81 | - 只有唯一的输入生命周期 82 | - 或者多个输入生命周期,但是函数必须有&self或&mut self接收者 83 | 84 | 在第一种情况下,输出生命周期被推断为和唯一的输入生命周期相同。第二种情况,输出生命周期被推断为和&self或&mut self的生命周期相同。 85 | 86 | 下面是一些省略生命周期的错误示例: 87 | 88 | 89 | ```rust 90 | 91 | // 错误,没有输入生命周期 92 | fn foo() -> &str { } 93 | 94 | // 错误,`x` 和 `y` 有不同的生命周期 95 | fn bar(x: &str, y: &str) -> &str { } 96 | 97 | // 错误, `y`的生命周期被推断为和`x`的不同 98 | fn baz<'a>(x: &'a str, y: &str) -> &str { } 99 | ``` 100 | 101 | 这里是有一些现在错误,但可能在未来的Rust版本中正确的示例: 102 | 103 | ```rust 104 | struct Foo<'a>(&'a str); 105 | 106 | trait Quux { } 107 | impl Quux for Foo { } 108 | ``` 109 | 110 | 省略`impl<'a'>`中的生命周期是lifetime elision RFC的一部分,然而[目前还未实现](https://github.com/rust-lang/rust/issues/15872). -------------------------------------------------------------------------------- /now/E0110.md: -------------------------------------------------------------------------------- 1 | # E0110 2 | 3 | --- 4 | 5 | 6 | You tried to give a lifetime parameter to a type which doesn't need it. Erroneous code example: 7 | 8 | ```rust 9 | 10 | type X = u32<'static>; // error: lifetime parameters are not allowed on 11 | // this type 12 | ``` 13 | 14 | Please check that the correct type was used and recheck its definition; perhaps it doesn't need the lifetime parameter. Example: 15 | 16 | ```rust 17 | type X = u32; // ok! 18 | ``` 19 | 20 | 21 | # E0110 22 | 23 | --- 24 | 25 | 你试图给一个不需要生命周期参数的类型赋予一个生命周期参数,错误代码如下: 26 | 27 | ```rust 28 | 29 | type X = u32<'static>; // error: 该类型不允许添加生命周期参数 30 | ``` 31 | 32 | 请检查是否使用正确的类型并重新检查其定义,也许它不需要生命周期参数。比如: 33 | 34 | ```rust 35 | type X = u32; // ok! 36 | ``` -------------------------------------------------------------------------------- /now/E0161.md: -------------------------------------------------------------------------------- 1 | # E0161 2 | 3 | --- 4 | 5 | A value was moved. However, its size was not known at compile time, and only values of a known size can be moved. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | #![feature(box_syntax)] 11 | 12 | fn main() { 13 | let array: &[isize] = &[1, 2, 3]; 14 | let _x: Box<[isize]> = box *array; 15 | // error: cannot move a value of type [isize]: the size of [isize] cannot 16 | // be statically determined 17 | } 18 | ``` 19 | 20 | In Rust, you can only move a value when its size is known at compile time. 21 | 22 | To work around this restriction, consider "hiding" the value behind a reference: either &x or &mut x. Since a reference has a fixed size, this lets you move it around as usual. Example: 23 | 24 | ``` 25 | #![feature(box_syntax)] 26 | 27 | fn main() { 28 | let array: &[isize] = &[1, 2, 3]; 29 | let _x: Box<&[isize]> = box array; // ok! 30 | } 31 | ``` 32 | 33 | 34 | # E0161 35 | 36 | --- 37 | 38 | 值的(所有权)被移动。然而,它的大小在编译期是未知的,仅允许已知大小的值转移(所有权)。 39 | 40 | 错误代码示例: 41 | 42 | ```rust 43 | #![feature(box_syntax)] 44 | 45 | fn main() { 46 | let array: &[isize] = &[1, 2, 3]; 47 | let _x: Box<[isize]> = box *array; 48 | // error: 不能移动类型为[isize]的值: [isize]的大小无法静态地确定 49 | } 50 | ``` 51 | 在Rust中,只能移动在编译期能确定大小的值。 52 | 53 | 要想解决此限制,请考虑将值“藏”于引用之后:&x 或 &mut x。因为引用有固定的大小,所以可以正常移动它。比如: 54 | 55 | ``` 56 | #![feature(box_syntax)] 57 | 58 | fn main() { 59 | let array: &[isize] = &[1, 2, 3]; 60 | let _x: Box<&[isize]> = box array; // ok! 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /now/E0195.md: -------------------------------------------------------------------------------- 1 | # E0195 2 | 3 | --- 4 | 5 | Your method's lifetime parameters do not match the trait declaration. Erroneous code example: 6 | 7 | ```rust 8 | 9 | trait Trait { 10 | fn bar<'a,'b:'a>(x: &'a str, y: &'b str); 11 | } 12 | 13 | struct Foo; 14 | 15 | impl Trait for Foo { 16 | fn bar<'a,'b>(x: &'a str, y: &'b str) { 17 | // error: lifetime parameters or bounds on method `bar` 18 | // do not match the trait declaration 19 | } 20 | } 21 | ``` 22 | 23 | The lifetime constraint 'b for bar() implementation does not match the trait declaration. Ensure lifetime declarations match exactly in both trait declaration and implementation. Example: 24 | 25 | ``` 26 | trait Trait { 27 | fn t<'a,'b:'a>(x: &'a str, y: &'b str); 28 | } 29 | 30 | struct Foo; 31 | 32 | impl Trait for Foo { 33 | fn t<'a,'b:'a>(x: &'a str, y: &'b str) { // ok! 34 | } 35 | } 36 | ``` 37 | 38 | # E0195 39 | 40 | --- 41 | 42 | 方法的生命周期参数和trait声明不匹配。错误代码如下所示: 43 | 44 | ```rust 45 | 46 | trait Trait { 47 | fn bar<'a,'b:'a>(x: &'a str, y: &'b str); 48 | } 49 | 50 | struct Foo; 51 | 52 | impl Trait for Foo { 53 | fn bar<'a,'b>(x: &'a str, y: &'b str) { 54 | // error: 方法`bar`的生命周期参数或限定不匹配该trait声明 55 | } 56 | } 57 | ``` 58 | 59 | bar()实现的生命周期约束'b和trait生命不匹配。确保生命周期完全符合trait声明和实现。比如: 60 | 61 | 62 | ``` 63 | trait Trait { 64 | fn t<'a,'b:'a>(x: &'a str, y: &'b str); 65 | } 66 | 67 | struct Foo; 68 | 69 | impl Trait for Foo { 70 | fn t<'a,'b:'a>(x: &'a str, y: &'b str) { // ok! 71 | } 72 | } 73 | ``` -------------------------------------------------------------------------------- /now/E0207.md: -------------------------------------------------------------------------------- 1 | # E0207 2 | 3 | --- 4 | 5 | Any type parameter or lifetime parameter of an impl must meet at least one of the following criteria: 6 | 7 | - it appears in the self type of the impl 8 | - for a trait impl, it appears in the trait reference 9 | - it is bound as an associated type 10 | 11 | ## Error example 1 12 | 13 | Suppose we have a struct Foo and we would like to define some methods for it. The following definition leads to a compiler error: 14 | 15 | ```rust 16 | struct Foo; 17 | 18 | impl Foo { 19 | // error: the type parameter `T` is not constrained by the impl trait, self 20 | // type, or predicates [E0207] 21 | fn get(&self) -> T { 22 | ::default() 23 | } 24 | } 25 | ``` 26 | 27 | The problem is that the parameter T does not appear in the self type (Foo) of the impl. In this case, we can fix the error by moving the type parameter from the impl to the method get: 28 | 29 | ```rust 30 | struct Foo; 31 | 32 | // Move the type parameter from the impl to the method 33 | impl Foo { 34 | fn get(&self) -> T { 35 | ::default() 36 | } 37 | } 38 | ``` 39 | 40 | ## Error example 2 41 | 42 | As another example, suppose we have a Maker trait and want to establish a type FooMaker that makes Foos: 43 | 44 | ```rust 45 | trait Maker { 46 | type Item; 47 | fn make(&mut self) -> Self::Item; 48 | } 49 | 50 | struct Foo { 51 | foo: T 52 | } 53 | 54 | struct FooMaker; 55 | 56 | impl Maker for FooMaker { 57 | // error: the type parameter `T` is not constrained by the impl trait, self 58 | // type, or predicates [E0207] 59 | type Item = Foo; 60 | 61 | fn make(&mut self) -> Foo { 62 | Foo { foo: ::default() } 63 | } 64 | } 65 | ``` 66 | 67 | This fails to compile because T does not appear in the trait or in the implementing type. 68 | 69 | One way to work around this is to introduce a phantom type parameter into FooMaker, like so: 70 | 71 | ```rust 72 | use std::marker::PhantomData; 73 | 74 | trait Maker { 75 | type Item; 76 | fn make(&mut self) -> Self::Item; 77 | } 78 | 79 | struct Foo { 80 | foo: T 81 | } 82 | 83 | // Add a type parameter to `FooMaker` 84 | struct FooMaker { 85 | phantom: PhantomData, 86 | } 87 | 88 | impl Maker for FooMaker { 89 | type Item = Foo; 90 | 91 | fn make(&mut self) -> Foo { 92 | Foo { 93 | foo: ::default(), 94 | } 95 | } 96 | } 97 | ``` 98 | 99 | Another way is to do away with the associated type in Maker and use an input type parameter instead: 100 | 101 | ```rust 102 | // Use a type parameter instead of an associated type here 103 | trait Maker { 104 | fn make(&mut self) -> Item; 105 | } 106 | 107 | struct Foo { 108 | foo: T 109 | } 110 | 111 | struct FooMaker; 112 | 113 | impl Maker> for FooMaker { 114 | fn make(&mut self) -> Foo { 115 | Foo { foo: ::default() } 116 | } 117 | } 118 | ``` 119 | 120 | Additional information 121 | --- 122 | For more information, please see [RFC 447](https://github.com/rust-lang/rfcs/blob/master/text/0447-no-unused-impl-parameters.md). 123 | 124 | 125 | # E0207 126 | 127 | --- 128 | 129 | `impl`的任何类型参数或生命周期参数必须至少满足下列标准之一: 130 | 131 | - impl self时,出现在self类型中 132 | - impl trait时,出现在trait中 133 | - 绑定为关联类型 134 | 135 | ## 错误示例 1 136 | 137 | 假设有一个结构体Foo,并为它定义一些方法。下面的定义会导致编译器错误: 138 | 139 | ```rust 140 | struct Foo; 141 | 142 | impl Foo { 143 | // error: 类型参数`T`并不受该impl trait, self类型或predicates的约束[E0207] 144 | fn get(&self) -> T { 145 | ::default() 146 | } 147 | } 148 | ``` 149 | 150 | 参数T并没有出现在impl self类型(Foo)中。在这个例子中,可以将类型参数从impl移到方法中来修复此错误: 151 | 152 | ```rust 153 | struct Foo; 154 | 155 | // 把类型参数T从impl中移到方法中 156 | impl Foo { 157 | fn get(&self) -> T { 158 | ::default() 159 | } 160 | } 161 | ``` 162 | 163 | ## 错误示例 2 164 | 165 | 另一个示例,假设有一个标记trait,并想创建一个类型FooMaker来制造更多的Foo : 166 | 167 | ```rust 168 | trait Maker { 169 | type Item; 170 | fn make(&mut self) -> Self::Item; 171 | } 172 | 173 | struct Foo { 174 | foo: T 175 | } 176 | 177 | struct FooMaker; 178 | 179 | impl Maker for FooMaker { 180 | // error: 类型参数`T`并不受该impl trait, self类型或predicates的约束[E0207] 181 | type Item = Foo; 182 | 183 | fn make(&mut self) -> Foo { 184 | Foo { foo: ::default() } 185 | } 186 | } 187 | ``` 188 | 189 | 这会编译失败,因为T没有出现在trait中或是在其实现的类型(FooMaker)中。解决此问题的一种方法是在FooMaker中加入phantom类型参数,就像这样: 190 | 191 | ```rust 192 | use std::marker::PhantomData; 193 | 194 | trait Maker { 195 | type Item; 196 | fn make(&mut self) -> Self::Item; 197 | } 198 | 199 | struct Foo { 200 | foo: T 201 | } 202 | 203 | // 为 `FooMaker` 增加类型参数 204 | struct FooMaker { 205 | phantom: PhantomData, 206 | } 207 | 208 | impl Maker for FooMaker { 209 | type Item = Foo; 210 | 211 | fn make(&mut self) -> Foo { 212 | Foo { 213 | foo: ::default(), 214 | } 215 | } 216 | } 217 | ``` 218 | 219 | 另一种方法是在Maker中取消关联类型,并使用输入类型参数: 220 | 221 | ```rust 222 | // 这里使用类型参数代替关联类型 223 | trait Maker { 224 | fn make(&mut self) -> Item; 225 | } 226 | 227 | struct Foo { 228 | foo: T 229 | } 230 | 231 | struct FooMaker; 232 | 233 | impl Maker> for FooMaker { 234 | fn make(&mut self) -> Foo { 235 | Foo { foo: ::default() } 236 | } 237 | } 238 | ``` 239 | 240 | 更多信息: 241 | --- 242 | 参阅 [RFC 447](https://github.com/rust-lang/rfcs/blob/master/text/0447-no-unused-impl-parameters.md). -------------------------------------------------------------------------------- /now/E0261.md: -------------------------------------------------------------------------------- 1 | # E0261 2 | 3 | --- 4 | 5 | When using a lifetime like 'a in a type, it must be declared before being used. 6 | 7 | These two examples illustrate the problem: 8 | 9 | ```rust 10 | // error, use of undeclared lifetime name `'a` 11 | fn foo(x: &'a str) { } 12 | 13 | struct Foo { 14 | // error, use of undeclared lifetime name `'a` 15 | x: &'a str, 16 | } 17 | ``` 18 | 19 | These can be fixed by declaring lifetime parameters: 20 | 21 | ```rust 22 | fn foo<'a>(x: &'a str) {} 23 | 24 | struct Foo<'a> { 25 | x: &'a str, 26 | } 27 | ``` 28 | 29 | # E0261 30 | 31 | --- 32 | 33 | 在类型中使用像'a这样的生命周期时,必须要先声明。 34 | 35 | 这两个例子说明了此问题: 36 | 37 | ```rust 38 | // error, 使用了未声明的生命周期名`'a` 39 | fn foo(x: &'a str) { } 40 | 41 | struct Foo { 42 | // error, 使用了未声明的生命周期名`'a` 43 | x: &'a str, 44 | } 45 | ``` 46 | 47 | 声明生命周期参数就可以解决此问题: 48 | 49 | ```rust 50 | fn foo<'a>(x: &'a str) {} 51 | 52 | struct Foo<'a> { 53 | x: &'a str, 54 | } 55 | ``` -------------------------------------------------------------------------------- /now/E0262.md: -------------------------------------------------------------------------------- 1 | # E0262 2 | 3 | --- 4 | 5 | Declaring certain lifetime names in parameters is disallowed. For example, because the 'static lifetime is a special built-in lifetime name denoting the lifetime of the entire program, this is an error: 6 | 7 | ```rust 8 | // error, invalid lifetime parameter name `'static` 9 | fn foo<'static>(x: &'static str) { } 10 | ``` 11 | 12 | # E0262 13 | 14 | --- 15 | 16 | 在参数中声明某些生命周期名称是不允许的。例如,因为'static生命周期是特殊的内置生命周期名称,表示整个程序的生命周期,下面是一个错误示例: 17 | 18 | ```rust 19 | // error, 无效的生命周期名称 `'static` 20 | fn foo<'static>(x: &'static str) { } 21 | ``` -------------------------------------------------------------------------------- /now/E0263.md: -------------------------------------------------------------------------------- 1 | # E0263 2 | 3 | --- 4 | 5 | A lifetime name cannot be declared more than once in the same scope. For example: 6 | 7 | ```rust 8 | 9 | // error, lifetime name `'a` declared twice in the same scope 10 | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } 11 | ``` 12 | 13 | # E0263 14 | 15 | --- 16 | 17 | 一个生命周期名称在同一个作用域中只能被声明一次: 18 | 19 | ```rust 20 | // error, 生命周期名字 `'a` 在同一个作用域中声明了两次 21 | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } 22 | ``` -------------------------------------------------------------------------------- /now/E0277.md: -------------------------------------------------------------------------------- 1 | # E0277 2 | 3 | --- 4 | 5 | You tried to use a type which doesn't implement some trait in a place which expected that trait. Erroneous code example: 6 | 7 | ```rust 8 | 9 | // here we declare the Foo trait with a bar method 10 | trait Foo { 11 | fn bar(&self); 12 | } 13 | 14 | // we now declare a function which takes an object implementing the Foo trait 15 | fn some_func(foo: T) { 16 | foo.bar(); 17 | } 18 | 19 | fn main() { 20 | // we now call the method with the i32 type, which doesn't implement 21 | // the Foo trait 22 | some_func(5i32); // error: the trait bound `i32 : Foo` is not satisfied 23 | } 24 | ``` 25 | 26 | In order to fix this error, verify that the type you're using does implement the trait. Example: 27 | 28 | ```rust 29 | trait Foo { 30 | fn bar(&self); 31 | } 32 | 33 | fn some_func(foo: T) { 34 | foo.bar(); // we can now use this method since i32 implements the 35 | // Foo trait 36 | } 37 | 38 | // we implement the trait on the i32 type 39 | impl Foo for i32 { 40 | fn bar(&self) {} 41 | } 42 | 43 | fn main() { 44 | some_func(5i32); // ok! 45 | } 46 | ``` 47 | 48 | Or in a generic context, an erroneous code example would look like: 49 | 50 | ```rust 51 | fn some_func(foo: T) { 52 | println!("{:?}", foo); // error: the trait `core::fmt::Debug` is not 53 | // implemented for the type `T` 54 | } 55 | 56 | fn main() { 57 | // We now call the method with the i32 type, 58 | // which *does* implement the Debug trait. 59 | some_func(5i32); 60 | } 61 | ``` 62 | 63 | Note that the error here is in the definition of the generic function: Although we only call it with a parameter that does implement Debug, the compiler still rejects the function: It must work with all possible input types. In order to make this example compile, we need to restrict the generic type we're accepting: 64 | 65 | ```rust 66 | use std::fmt; 67 | 68 | // Restrict the input type to types that implement Debug. 69 | fn some_func(foo: T) { 70 | println!("{:?}", foo); 71 | } 72 | 73 | fn main() { 74 | // Calling the method is still fine, as i32 implements Debug. 75 | some_func(5i32); 76 | 77 | // This would fail to compile now: 78 | // struct WithoutDebug; 79 | // some_func(WithoutDebug); 80 | } 81 | ``` 82 | 83 | Rust only looks at the signature of the called function, as such it must already specify all requirements that will be used for every type parameter. 84 | 85 | # E0277 86 | 87 | --- 88 | 89 | You tried to use a type which doesn't implement some trait in a place which expected that trait. Erroneous code example: 90 | 91 | ```rust 92 | 93 | // here we declare the Foo trait with a bar method 94 | trait Foo { 95 | fn bar(&self); 96 | } 97 | 98 | // we now declare a function which takes an object implementing the Foo trait 99 | fn some_func(foo: T) { 100 | foo.bar(); 101 | } 102 | 103 | fn main() { 104 | // we now call the method with the i32 type, which doesn't implement 105 | // the Foo trait 106 | some_func(5i32); // error: the trait bound `i32 : Foo` is not satisfied 107 | } 108 | ``` 109 | 110 | In order to fix this error, verify that the type you're using does implement the trait. Example: 111 | 112 | ```rust 113 | trait Foo { 114 | fn bar(&self); 115 | } 116 | 117 | fn some_func(foo: T) { 118 | foo.bar(); // we can now use this method since i32 implements the 119 | // Foo trait 120 | } 121 | 122 | // we implement the trait on the i32 type 123 | impl Foo for i32 { 124 | fn bar(&self) {} 125 | } 126 | 127 | fn main() { 128 | some_func(5i32); // ok! 129 | } 130 | ``` 131 | 132 | Or in a generic context, an erroneous code example would look like: 133 | 134 | ```rust 135 | fn some_func(foo: T) { 136 | println!("{:?}", foo); // error: the trait `core::fmt::Debug` is not 137 | // implemented for the type `T` 138 | } 139 | 140 | fn main() { 141 | // We now call the method with the i32 type, 142 | // which *does* implement the Debug trait. 143 | some_func(5i32); 144 | } 145 | ``` 146 | 147 | Note that the error here is in the definition of the generic function: Although we only call it with a parameter that does implement Debug, the compiler still rejects the function: It must work with all possible input types. In order to make this example compile, we need to restrict the generic type we're accepting: 148 | 149 | ```rust 150 | use std::fmt; 151 | 152 | // Restrict the input type to types that implement Debug. 153 | fn some_func(foo: T) { 154 | println!("{:?}", foo); 155 | } 156 | 157 | fn main() { 158 | // Calling the method is still fine, as i32 implements Debug. 159 | some_func(5i32); 160 | 161 | // This would fail to compile now: 162 | // struct WithoutDebug; 163 | // some_func(WithoutDebug); 164 | } 165 | ``` 166 | 167 | Rust only looks at the signature of the called function, as such it must already specify all requirements that will be used for every type parameter. -------------------------------------------------------------------------------- /now/E0303.md: -------------------------------------------------------------------------------- 1 | # E0303 2 | 3 | --- 4 | 5 | In certain cases it is possible for sub-bindings to violate memory safety. Updates to the borrow checker in a future version of Rust may remove this restriction, but for now patterns must be rewritten without sub-bindings. 6 | 7 | Before: 8 | 9 | ```rust 10 | match Some("hi".to_string()) { 11 | ref op_string_ref @ Some(s) => {}, 12 | None => {}, 13 | } 14 | ``` 15 | 16 | After: 17 | 18 | ```rust 19 | match Some("hi".to_string()) { 20 | Some(ref s) => { 21 | let op_string_ref = &Some(s); 22 | // ... 23 | }, 24 | None => {}, 25 | } 26 | ``` 27 | 28 | The op_string_ref binding has type &Option<&String> in both cases. 29 | 30 | See also [https://github.com/rust-lang/rust/issues/14587](https://github.com/rust-lang/rust/issues/14587) 31 | 32 | # E0303 33 | 34 | --- 35 | 36 | 在某些情况下,子绑定(sub-bindings)可能会违反内存安全。 在Rust的未来版本中,借用检查器更新可能会删除此限制,但是现在,模式必须重写而无需子绑定。 37 | 38 | 39 | 之前: 40 | 41 | ```rust 42 | match Some("hi".to_string()) { 43 | ref op_string_ref @ Some(s) => {}, 44 | None => {}, 45 | } 46 | ``` 47 | 上面代码编译会出错: 48 | 49 | ```rust 50 | error[E0009]: cannot bind by-move and by-ref in the same pattern 51 | --> src/main.rs:3:30 52 | | 53 | 3 | ref op_string_ref @ Some(s) => {}, 54 | | -------------------------^- 55 | | | | 56 | | | by-move pattern here 57 | | both by-ref and by-move used 58 | ``` 59 | 60 | 61 | 之后: 62 | 63 | ```rust 64 | match Some("hi".to_string()) { 65 | Some(ref s) => { 66 | let op_string_ref = &Some(s); 67 | // ... 68 | }, 69 | None => {}, 70 | } 71 | ``` 72 | 73 | 上述两种情况,op_string_ref绑定都有&Option <&String>类型。 74 | 75 | 也可参阅 [https://github.com/rust-lang/rust/issues/14587](https://github.com/rust-lang/rust/issues/14587) -------------------------------------------------------------------------------- /now/E0309.md: -------------------------------------------------------------------------------- 1 | # E0309 2 | 3 | --- 4 | 5 | Types in type definitions have lifetimes associated with them that represent how long the data stored within them is guaranteed to be live. This lifetime must be as long as the data needs to be alive, and missing the constraint that denotes this will cause this error. 6 | 7 | ```rust 8 | // This won't compile because T is not constrained, meaning the data 9 | // stored in it is not guaranteed to last as long as the reference 10 | struct Foo<'a, T> { 11 | foo: &'a T 12 | } 13 | ``` 14 | 15 | This will compile, because it has the constraint on the type parameter: 16 | 17 | ```rust 18 | struct Foo<'a, T: 'a> { 19 | foo: &'a T 20 | } 21 | ``` 22 | 23 | To see why this is important, consider the case where T is itself a reference (e.g., T = &str). If we don't include the restriction that T: 'a, the following code would be perfectly legal: 24 | 25 | ```rust 26 | struct Foo<'a, T> { 27 | foo: &'a T 28 | } 29 | 30 | fn main() { 31 | let v = "42".to_string(); 32 | let f = Foo{foo: &v}; 33 | drop(v); 34 | println!("{}", f.foo); // but we've already dropped v! 35 | } 36 | ``` 37 | 38 | # E0309 39 | 40 | --- 41 | 42 | 类型定义中的类型包含与其关联的生命周期,表示存储于其中的数据的生命周期。这个生命周期必须要和数据一样长,如果缺少这份约束将导致错误。 43 | 44 | 45 | ```rust 46 | // 该代码将会编译失败,因为T不受约束,这表示存储的数据不能保证存活时间长于引用 47 | struct Foo<'a, T> { 48 | foo: &'a T 49 | } 50 | ``` 51 | 52 | 下面代码会正常编译,因为类型参数具有了约束: 53 | 54 | ```rust 55 | struct Foo<'a, T: 'a> { 56 | foo: &'a T 57 | } 58 | ``` 59 | 60 | 想了解这为什么重要,可以思考T作为一个引用(T=&str)的例子。如果没有包括 T: 'a的限制,以下代码将完全合法。 61 | 62 | 63 | ```rust 64 | struct Foo<'a, T> { 65 | foo: &'a T 66 | } 67 | 68 | fn main() { 69 | let v = "42".to_string(); 70 | let f = Foo{foo: &v}; 71 | drop(v); 72 | println!("{}", f.foo); // 但是v已经被drop了,悬垂指针! 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /now/E0310.md: -------------------------------------------------------------------------------- 1 | # E0310 2 | 3 | --- 4 | 5 | Types in type definitions have lifetimes associated with them that represent how long the data stored within them is guaranteed to be live. This lifetime must be as long as the data needs to be alive, and missing the constraint that denotes this will cause this error. 6 | 7 | ``` 8 | // This won't compile because T is not constrained to the static lifetime 9 | // the reference needs 10 | struct Foo { 11 | foo: &'static T 12 | } 13 | ``` 14 | 15 | This will compile, because it has the constraint on the type parameter: 16 | 17 | ```rust 18 | struct Foo { 19 | foo: &'static T 20 | } 21 | ``` 22 | 23 | # E0310 24 | 25 | --- 26 | 类型定义中的类型包含与其关联的生命周期,表示存储于其中的数据的生命周期。这个生命周期必须要和数据一样长,如果缺少这份约束将导致错误。 27 | 28 | 29 | ``` 30 | // 下面代码将不会编译,因为类型T没有引用需要的静态(static)生命周期约束 31 | struct Foo { 32 | foo: &'static T 33 | } 34 | ``` 35 | 36 | 下面代码会编译: 37 | 38 | ```rust 39 | struct Foo { 40 | foo: &'static T 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /now/E0312.md: -------------------------------------------------------------------------------- 1 | # E0312 2 | 3 | --- 4 | 5 | A lifetime of reference outlives lifetime of borrowed content. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | fn make_child<'human, 'elve>(x: &mut &'human isize, y: &mut &'elve isize) { 11 | *x = *y; 12 | // error: lifetime of reference outlives lifetime of borrowed content 13 | } 14 | ``` 15 | 16 | The compiler cannot determine if the human lifetime will live long enough to keep up on the elve one. To solve this error, you have to give an explicit lifetime hierarchy: 17 | 18 | ```rust 19 | fn make_child<'human, 'elve: 'human>(x: &mut &'human isize, 20 | y: &mut &'elve isize) { 21 | *x = *y; // ok! 22 | } 23 | ``` 24 | 25 | Or use the same lifetime for every variable: 26 | 27 | ```rust 28 | fn make_child<'elve>(x: &mut &'elve isize, y: &mut &'elve isize) { 29 | *x = *y; // ok! 30 | } 31 | ``` 32 | 33 | # E0312 34 | 35 | --- 36 | 37 | 引用的生命周期活得长于借用的内容。 38 | 39 | 错误示例如下: 40 | 41 | ```rust 42 | fn make_child<'human, 'elve>(x: &mut &'human isize, y: &mut &'elve isize) { 43 | *x = *y; 44 | // error: 引用的生命周期活得长于借用的内容。 45 | } 46 | ``` 47 | 48 | 编译器无法确定human的生命周期是否能够存活的比elve要长。要解决这个问题,必须明确的给定生命周期包含关系。 49 | 50 | 51 | ```rust 52 | fn make_child<'human, 'elve: 'human>(x: &mut &'human isize, 53 | y: &mut &'elve isize) { 54 | *x = *y; // ok! 55 | } 56 | ``` 57 | 58 | 或者每个参数都使用相同的生命周期参数: 59 | 60 | ```rust 61 | fn make_child<'elve>(x: &mut &'elve isize, y: &mut &'elve isize) { 62 | *x = *y; // ok! 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /now/E0382.md: -------------------------------------------------------------------------------- 1 | # E0382 2 | 3 | --- 4 | 5 | This error occurs when an attempt is made to use a variable after its contents have been moved elsewhere. For example: 6 | 7 | ```rust 8 | struct MyStruct { s: u32 } 9 | 10 | fn main() { 11 | let mut x = MyStruct{ s: 5u32 }; 12 | let y = x; 13 | x.s = 6; 14 | println!("{}", x.s); 15 | } 16 | ``` 17 | 18 | Since MyStruct is a type that is not marked Copy, the data gets moved out of x when we set y. This is fundamental to Rust's ownership system: outside of workarounds like Rc, a value cannot be owned by more than one variable. 19 | 20 | If we own the type, the easiest way to address this problem is to implement Copy and Clone on it, as shown below. This allows y to copy the information in x, while leaving the original version owned by x. Subsequent changes to x will not be reflected when accessing y. 21 | 22 | ``` 23 | #[derive(Copy, Clone)] 24 | struct MyStruct { s: u32 } 25 | 26 | fn main() { 27 | let mut x = MyStruct{ s: 5u32 }; 28 | let y = x; 29 | x.s = 6; 30 | println!("{}", x.s); 31 | } 32 | ``` 33 | 34 | Alternatively, if we don't control the struct's definition, or mutable shared ownership is truly required, we can use Rc and RefCell: 35 | 36 | ``` 37 | use std::cell::RefCell; 38 | use std::rc::Rc; 39 | 40 | struct MyStruct { s: u32 } 41 | 42 | fn main() { 43 | let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 })); 44 | let y = x.clone(); 45 | x.borrow_mut().s = 6; 46 | println!("{}", x.borrow().s); 47 | } 48 | ``` 49 | 50 | With this approach, x and y share ownership of the data via the Rc (reference count type). RefCell essentially performs runtime borrow checking: ensuring that at most one writer or multiple readers can access the data at any one time. 51 | 52 | If you wish to learn more about ownership in Rust, start with the chapter in the Book: 53 | 54 | [https://doc.rust-lang.org/book/first-edition/ownership.html](https://doc.rust-lang.org/book/first-edition/ownership.html) 55 | 56 | # E0382 57 | 58 | --- 59 | 60 | 当尝试使用一个值已经被移动到其他位置的变量会发生此错误。例如: 61 | 62 | 63 | ```rust 64 | struct MyStruct { s: u32 } 65 | 66 | fn main() { 67 | let mut x = MyStruct{ s: 5u32 }; 68 | let y = x; 69 | x.s = 6; 70 | println!("{}", x.s); 71 | } 72 | ``` 73 | 74 | 因为MyStruct是没有被标记为Copy的类型,所以,当设置y时,数据将从x移出。这是Rust所有权系统的基础:一个值不能被多个变量拥有,除非使用Rc。 75 | 76 | 如果想拥有这种类型,最容易的办法是为其实现Copy和Clone,如下所示。这允许y去复制x中的信息,同时保留x的原始版本,对x的后续更改将不会影响到y的访问。 77 | 78 | ``` 79 | #[derive(Copy, Clone)] 80 | struct MyStruct { s: u32 } 81 | 82 | fn main() { 83 | let mut x = MyStruct{ s: 5u32 }; 84 | let y = x; 85 | x.s = 6; 86 | println!("{}", x.s); 87 | } 88 | ``` 89 | 90 | 或者,可以不控制结构体的定义,也许共享可变的所有权才是真正的需求,可以用Rc和RefCell: 91 | 92 | 93 | ``` 94 | use std::cell::RefCell; 95 | use std::rc::Rc; 96 | 97 | struct MyStruct { s: u32 } 98 | 99 | fn main() { 100 | let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 })); 101 | let y = x.clone(); 102 | x.borrow_mut().s = 6; 103 | println!("{}", x.borrow().s); 104 | } 105 | ``` 106 | 107 | 通过这种方法,x和y可以通过Rc(引用计数类型)共享数据的所有权。RefCell基本上执行运行时借用检查:确保每次最多一个写入访问或者多个读取访问。 108 | 109 | 如果你想学习Rust所有权的更多内容,可以参阅下面这本书的所有权章节: 110 | 111 | [https://doc.rust-lang.org/book/first-edition/ownership.html](https://doc.rust-lang.org/book/first-edition/ownership.html) -------------------------------------------------------------------------------- /now/E0392.md: -------------------------------------------------------------------------------- 1 | # E0392 2 | 3 | --- 4 | 5 | This error indicates that a type or lifetime parameter has been declared but not actually used. Here is an example that demonstrates the error: 6 | 7 | ```rust 8 | enum Foo { 9 | Bar, 10 | } 11 | ``` 12 | 13 | If the type parameter was included by mistake, this error can be fixed by simply removing the type parameter, as shown below: 14 | 15 | ```rust 16 | enum Foo { 17 | Bar, 18 | } 19 | ``` 20 | 21 | Alternatively, if the type parameter was intentionally inserted, it must be used. A simple fix is shown below: 22 | 23 | ``` 24 | enum Foo { 25 | Bar(T), 26 | } 27 | ``` 28 | 29 | This error may also commonly be found when working with unsafe code. For example, when using raw pointers one may wish to specify the lifetime for which the pointed-at data is valid. An initial attempt (below) causes this error: 30 | 31 | ```rust 32 | struct Foo<'a, T> { 33 | x: *const T, 34 | } 35 | ``` 36 | 37 | We want to express the constraint that Foo should not outlive 'a, because the data pointed to by T is only valid for that lifetime. The problem is that there are no actual uses of 'a. It's possible to work around this by adding a PhantomData type to the struct, using it to tell the compiler to act as if the struct contained a borrowed reference &'a T: 38 | 39 | ```rust 40 | use std::marker::PhantomData; 41 | 42 | struct Foo<'a, T: 'a> { 43 | x: *const T, 44 | phantom: PhantomData<&'a T> 45 | } 46 | ``` 47 | 48 | [PhantomData](https://doc.rust-lang.org/std/marker/struct.PhantomData.html) can also be used to express information about unused type parameters. 49 | 50 | 51 | # E0392 52 | 53 | --- 54 | 55 | 该错误表明,类型或生命周期参数已经被声明,但未被使用。以下是演示错误的示例: 56 | 57 | 58 | ```rust 59 | enum Foo { 60 | Bar, 61 | } 62 | ``` 63 | 64 | 如果本来就无需包含类型参数,只需要删除多余的类型参数即可修复此错误: 65 | 66 | ```rust 67 | enum Foo { 68 | Bar, 69 | } 70 | ``` 71 | 72 | 如果是有意的声明类型参数,则必须使用它: 73 | 74 | ``` 75 | enum Foo { 76 | Bar(T), 77 | } 78 | ``` 79 | 80 | 使用unsafe代码时候,也会发现此错误。例如,当使用原始指针时,可能希望为有效数据指定生命周期。以下代码会导致此错误: 81 | 82 | 83 | ```rust 84 | struct Foo<'a, T> { 85 | x: *const T, 86 | } 87 | ``` 88 | 89 | 我们想表达Foo不应该超过(outlive)'a的约束,因为T所指的数据仅对该生命周期有效。问题是,这里没有实际使用'a。可以通过向结构体添加PhantomData类型来解决这个问题,使用它来让编译器以为结构体中包含了一个借用 &'a T: 90 | 91 | 92 | 93 | ```rust 94 | use std::marker::PhantomData; 95 | 96 | struct Foo<'a, T: 'a> { 97 | x: *const T, 98 | phantom: PhantomData<&'a T> 99 | } 100 | ``` 101 | 102 | [PhantomData](https://doc.rust-lang.org/std/marker/struct.PhantomData.html) 也可用于表示未使用的类型参数的信息。 103 | -------------------------------------------------------------------------------- /now/E0478.md: -------------------------------------------------------------------------------- 1 | # E0478 2 | 3 | --- 4 | 5 | A lifetime bound was not satisfied. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | 11 | // Check that the explicit lifetime bound (`'SnowWhite`, in this example) must 12 | // outlive all the superbounds from the trait (`'kiss`, in this example). 13 | 14 | trait Wedding<'t>: 't { } 15 | 16 | struct Prince<'kiss, 'SnowWhite> { 17 | child: Box + 'SnowWhite>, 18 | // error: lifetime bound not satisfied 19 | } 20 | ``` 21 | 22 | In this example, the 'SnowWhite lifetime is supposed to outlive the 'kiss lifetime but the declaration of the Prince struct doesn't enforce it. To fix this issue, you need to specify it: 23 | 24 | ```rust 25 | trait Wedding<'t>: 't { } 26 | 27 | struct Prince<'kiss, 'SnowWhite: 'kiss> { // You say here that 'kiss must live 28 | // longer than 'SnowWhite. 29 | child: Box + 'SnowWhite>, // And now it's all good! 30 | } 31 | ``` 32 | 33 | # E0478 34 | 35 | --- 36 | 37 | 生命周期限定不匹配。 38 | 39 | 错误代码示例: 40 | 41 | ```rust 42 | 43 | // 检查显式的生命周期限定(本例中的`'SnowWhite`)必须超过所有来自trait的父限定(本例中的`'kiss`) 44 | 45 | trait Wedding<'t>: 't { } 46 | 47 | struct Prince<'kiss, 'SnowWhite> { 48 | child: Box + 'SnowWhite>, 49 | // error: 生命周期限定不匹配 50 | } 51 | ``` 52 | 本例中,'SnowWhite生命周期应该超过'kiss生命周期,但是Prince结构体并没有体现这一点。解决这个问题只需要指定它: 53 | 54 | 55 | ```rust 56 | trait Wedding<'t>: 't { } 57 | 58 | struct Prince<'kiss, 'SnowWhite: 'kiss> { // 'kiss 必须存活得比'SnowWhite更长 59 | child: Box + 'SnowWhite>, // 现在一切OK 60 | } 61 | ``` 62 | -------------------------------------------------------------------------------- /now/E0491.md: -------------------------------------------------------------------------------- 1 | # E0491 2 | 3 | --- 4 | 5 | A reference has a longer lifetime than the data it references. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | // struct containing a reference requires a lifetime parameter, 11 | // because the data the reference points to must outlive the struct (see E0106) 12 | struct Struct<'a> { 13 | ref_i32: &'a i32, 14 | } 15 | 16 | // However, a nested struct like this, the signature itself does not tell 17 | // whether 'a outlives 'b or the other way around. 18 | // So it could be possible that 'b of reference outlives 'a of the data. 19 | struct Nested<'a, 'b> { 20 | ref_struct: &'b Struct<'a>, // compile error E0491 21 | } 22 | 23 | ``` 24 | 25 | To fix this issue, you can specify a bound to the lifetime like below: 26 | 27 | ``` 28 | struct Struct<'a> { 29 | ref_i32: &'a i32, 30 | } 31 | 32 | // 'a: 'b means 'a outlives 'b 33 | struct Nested<'a: 'b, 'b> { 34 | ref_struct: &'b Struct<'a>, 35 | } 36 | ``` 37 | 38 | # E0491 39 | 40 | --- 41 | 42 | 引用的生命周期长于其引用的数据。 43 | 44 | 45 | 错误代码示例: 46 | 47 | ```rust 48 | // 包含引用的结构体需要生命周期参数,因为引用的数据必须活得比结构体长(参见E0106) 49 | struct Struct<'a> { 50 | ref_i32: &'a i32, 51 | } 52 | 53 | // 然而,像这样一个嵌套结构体,签名本身并不能告诉你'a是否获得比'b长,或者其他信息。所以,引用'b 有可能活得比数据'a要长。 54 | struct Nested<'a, 'b> { 55 | ref_struct: &'b Struct<'a>, // 编译错误 E0491 56 | } 57 | 58 | ``` 59 | 60 | 要修复此错误,只需要按如下指定生命周期限定: 61 | 62 | ``` 63 | struct Struct<'a> { 64 | ref_i32: &'a i32, 65 | } 66 | 67 | // 'a: 'b 意味着 'a 超过 'b 68 | struct Nested<'a: 'b, 'b> { 69 | ref_struct: &'b Struct<'a>, 70 | } 71 | ``` 72 | -------------------------------------------------------------------------------- /now/E0496.md: -------------------------------------------------------------------------------- 1 | # E0496 2 | 3 | --- 4 | 5 | A lifetime name is shadowing another lifetime name. Erroneous code example: 6 | 7 | ```rust 8 | struct Foo<'a> { 9 | a: &'a i32, 10 | } 11 | 12 | impl<'a> Foo<'a> { 13 | fn f<'a>(x: &'a i32) { // error: lifetime name `'a` shadows a lifetime 14 | // name that is already in scope 15 | } 16 | } 17 | ``` 18 | 19 | Please change the name of one of the lifetimes to remove this error. Example: 20 | 21 | ```rust 22 | struct Foo<'a> { 23 | a: &'a i32, 24 | } 25 | 26 | impl<'a> Foo<'a> { 27 | fn f<'b>(x: &'b i32) { // ok! 28 | } 29 | } 30 | 31 | fn main() { 32 | } 33 | ``` 34 | 35 | 36 | # E0496 37 | 38 | --- 39 | 40 | 生命周期名称正在屏蔽另一个生命周期名称。错误代码示例: 41 | 42 | 43 | ```rust 44 | struct Foo<'a> { 45 | a: &'a i32, 46 | } 47 | 48 | impl<'a> Foo<'a> { 49 | fn f<'a>(x: &'a i32) { // error: 生命周期名称`'a` 屏蔽了当前作用域中另一个生命周期名称 50 | } 51 | } 52 | ``` 53 | 54 | 通过修改名称修复此错误,示例如下: 55 | 56 | ```rust 57 | struct Foo<'a> { 58 | a: &'a i32, 59 | } 60 | 61 | impl<'a> Foo<'a> { 62 | fn f<'b>(x: &'b i32) { // ok! 63 | } 64 | } 65 | 66 | fn main() { 67 | } 68 | ``` 69 | -------------------------------------------------------------------------------- /now/E0505.md: -------------------------------------------------------------------------------- 1 | # E0505 2 | 3 | --- 4 | 5 | A value was moved out while it was still borrowed. 6 | 7 | Erroneous code example: 8 | 9 | ⓘ This example deliberately fails to compile 10 | 11 | ```rust 12 | struct Value {} 13 | 14 | fn eat(val: Value) {} 15 | 16 | fn main() { 17 | let x = Value{}; 18 | { 19 | let _ref_to_val: &Value = &x; 20 | eat(x); 21 | } 22 | } 23 | 24 | ``` 25 | 26 | Here, the function eat takes the ownership of x. 27 | However, x cannot be moved because it was borrowed to `_ref_to_val`. 28 | 29 | To fix that you can do few different things: 30 | 31 | - Try to avoid moving the variable. 32 | - Release borrow before move. 33 | - Implement the Copy trait on the type. 34 | 35 | Examples: 36 | 37 | ```rust 38 | struct Value {} 39 | 40 | fn eat(val: &Value) {} 41 | 42 | fn main() { 43 | let x = Value{}; 44 | { 45 | let _ref_to_val: &Value = &x; 46 | eat(&x); // pass by reference, if it's possible 47 | } 48 | } 49 | ``` 50 | 51 | Or: 52 | 53 | ```rust 54 | 55 | struct Value {} 56 | 57 | fn eat(val: Value) {} 58 | 59 | fn main() { 60 | let x = Value{}; 61 | { 62 | let _ref_to_val: &Value = &x; 63 | } 64 | eat(x); // release borrow and then move it. 65 | } 66 | ``` 67 | 68 | Or: 69 | 70 | ```rust 71 | #[derive(Clone, Copy)] // implement Copy trait 72 | struct Value {} 73 | 74 | fn eat(val: Value) {} 75 | 76 | fn main() { 77 | let x = Value{}; 78 | { 79 | let _ref_to_val: &Value = &x; 80 | eat(x); // it will be copied here. 81 | } 82 | } 83 | 84 | ``` 85 | 86 | You can find more information about borrowing in the rust-book: [http://doc.rust-lang.org/stable/book/references-and-borrowing.html](http://doc.rust-lang.org/stable/book/references-and-borrowing.html) 87 | 88 | # E0505 89 | 90 | --- 91 | 92 | 一个值在依然被借用之时,就被移出作用域。 93 | 94 | 95 | 错误代码示例: 96 | 97 | ⓘ 该示例编译失败乃故意为之 98 | 99 | ```rust 100 | struct Value {} 101 | 102 | fn eat(val: Value) {} 103 | 104 | fn main() { 105 | let x = Value{}; 106 | { 107 | let _ref_to_val: &Value = &x; 108 | eat(x); 109 | } 110 | } 111 | 112 | ``` 113 | 114 | 这里函数`eat`拿走了`x`的所有权。然而,`x`不能被move,因为它还在被`_ref_to_val`借用着。 115 | 116 | 有多种方法来解决此问题: 117 | 118 | - 避免move该变量。 119 | - 在move之前释放借用。 120 | - 为该类型实现Copy trait。 121 | 122 | 示例: 123 | 124 | ```rust 125 | struct Value {} 126 | 127 | fn eat(val: &Value) {} 128 | 129 | fn main() { 130 | let x = Value{}; 131 | { 132 | let _ref_to_val: &Value = &x; 133 | eat(&x); // 传递引用来避免move所有权 134 | } 135 | } 136 | ``` 137 | 138 | 或: 139 | 140 | ```rust 141 | 142 | struct Value {} 143 | 144 | fn eat(val: Value) {} 145 | 146 | fn main() { 147 | let x = Value{}; 148 | { 149 | let _ref_to_val: &Value = &x; 150 | } 151 | eat(x); // 在move之前归还所有权 152 | } 153 | ``` 154 | 155 | Or: 156 | 157 | ```rust 158 | #[derive(Clone, Copy)] // 实现 Copy trait 159 | struct Value {} 160 | 161 | fn eat(val: Value) {} 162 | 163 | fn main() { 164 | let x = Value{}; 165 | { 166 | let _ref_to_val: &Value = &x; 167 | eat(x); // 这里会由拷贝代替Move 168 | } 169 | } 170 | 171 | ``` 172 | 173 | 可以在此书中找到更多关于借用的信息: [rust-book](http://doc.rust-lang.org/stable/book/references-and-borrowing.html) 174 | -------------------------------------------------------------------------------- /now/E0509.md: -------------------------------------------------------------------------------- 1 | # E0509 2 | 3 | --- 4 | 5 | This error occurs when an attempt is made to move out of a value whose type implements the Drop trait. 6 | 7 | Example of erroneous code: 8 | 9 | ```rust 10 | //This example deliberately fails to compile 11 | struct FancyNum { 12 | num: usize 13 | } 14 | 15 | struct DropStruct { 16 | fancy: FancyNum 17 | } 18 | 19 | impl Drop for DropStruct { 20 | fn drop(&mut self) { 21 | // Destruct DropStruct, possibly using FancyNum 22 | } 23 | } 24 | 25 | fn main() { 26 | let drop_struct = DropStruct{fancy: FancyNum{num: 5}}; 27 | let fancy_field = drop_struct.fancy; // Error E0509 28 | println!("Fancy: {}", fancy_field.num); 29 | // implicit call to `drop_struct.drop()` as drop_struct goes out of scope 30 | } 31 | 32 | ``` 33 | 34 | Here, we tried to move a field out of a struct of type DropStruct which implements the Drop trait. However, a struct cannot be dropped if one or more of its fields have been moved. 35 | 36 | Structs implementing the Drop trait have an implicit destructor that gets called when they go out of scope. This destructor may use the fields of the struct, so moving out of the struct could make it impossible to run the destructor. Therefore, we must think of all values whose type implements the Drop trait as single units whose fields cannot be moved. 37 | 38 | This error can be fixed by creating a reference to the fields of a struct, enum, or tuple using the ref keyword: 39 | 40 | ```rust 41 | 42 | struct FancyNum { 43 | num: usize 44 | } 45 | 46 | struct DropStruct { 47 | fancy: FancyNum 48 | } 49 | 50 | impl Drop for DropStruct { 51 | fn drop(&mut self) { 52 | // Destruct DropStruct, possibly using FancyNum 53 | } 54 | } 55 | 56 | fn main() { 57 | let drop_struct = DropStruct{fancy: FancyNum{num: 5}}; 58 | let ref fancy_field = drop_struct.fancy; // No more errors! 59 | println!("Fancy: {}", fancy_field.num); 60 | // implicit call to `drop_struct.drop()` as drop_struct goes out of scope 61 | } 62 | ``` 63 | 64 | Note that this technique can also be used in the arms of a match expression: 65 | 66 | ```rust 67 | struct FancyNum { 68 | num: usize 69 | } 70 | 71 | enum DropEnum { 72 | Fancy(FancyNum) 73 | } 74 | 75 | impl Drop for DropEnum { 76 | fn drop(&mut self) { 77 | // Destruct DropEnum, possibly using FancyNum 78 | } 79 | } 80 | 81 | fn main() { 82 | // Creates and enum of type `DropEnum`, which implements `Drop` 83 | let drop_enum = DropEnum::Fancy(FancyNum{num: 10}); 84 | match drop_enum { 85 | // Creates a reference to the inside of `DropEnum::Fancy` 86 | DropEnum::Fancy(ref fancy_field) => // No error! 87 | println!("It was fancy-- {}!", fancy_field.num), 88 | } 89 | // implicit call to `drop_enum.drop()` as drop_enum goes out of scope 90 | } 91 | ``` 92 | 93 | # E0509 94 | 95 | --- 96 | 97 | 当尝试move出一个实现了Drop trait的某个类型的值的时候,会发生此错误。 98 | 99 | 错误代码示例: 100 | 101 | ```rust 102 | //此错误乃故意为之 103 | struct FancyNum { 104 | num: usize 105 | } 106 | 107 | struct DropStruct { 108 | fancy: FancyNum 109 | } 110 | 111 | impl Drop for DropStruct { 112 | fn drop(&mut self) { 113 | // Destruct DropStruct, possibly using FancyNum 114 | } 115 | } 116 | 117 | fn main() { 118 | let drop_struct = DropStruct{fancy: FancyNum{num: 5}}; 119 | let fancy_field = drop_struct.fancy; // Error E0509 120 | println!("Fancy: {}", fancy_field.num); 121 | // 超出此作用域会隐式调用析构函数 `drop_struct.drop()` 122 | } 123 | 124 | ``` 125 | 126 | 这里尝试将字段从实现了Drop trait的DropStruct结构体中move走所有权。然而,如果一个或多个字段被move,则该结构体将不能被Drop。 127 | 128 | 实现Drop trait的结构体在它们超出作用域时有一个隐式析构函数。该析构函数可能用到结构体中的字段,所以移出结构体字段将导致析构函数无法运行。因此,将实现了Drop trait的类型中所有字段值都视为无法被move的独立单元。 129 | 130 | 该错误可以通过使用ref关键字来创建结构体,枚举或元组的字段的引用来解决: 131 | 132 | ```rust 133 | 134 | struct FancyNum { 135 | num: usize 136 | } 137 | 138 | struct DropStruct { 139 | fancy: FancyNum 140 | } 141 | 142 | impl Drop for DropStruct { 143 | fn drop(&mut self) { 144 | // Destruct DropStruct, possibly using FancyNum 145 | } 146 | } 147 | 148 | fn main() { 149 | let drop_struct = DropStruct{fancy: FancyNum{num: 5}}; 150 | let ref fancy_field = drop_struct.fancy; // 不再报错! 151 | println!("Fancy: {}", fancy_field.num); 152 | // 超出此作用域会隐式调用析构函数 `drop_struct.drop()` 153 | } 154 | ``` 155 | 156 | 也可用于match匹配: 157 | 158 | ```rust 159 | struct FancyNum { 160 | num: usize 161 | } 162 | 163 | enum DropEnum { 164 | Fancy(FancyNum) 165 | } 166 | 167 | impl Drop for DropEnum { 168 | fn drop(&mut self) { 169 | // Destruct DropEnum, possibly using FancyNum 170 | } 171 | } 172 | 173 | fn main() { 174 | // Creates and enum of type `DropEnum`, which implements `Drop` 175 | let drop_enum = DropEnum::Fancy(FancyNum{num: 10}); 176 | match drop_enum { 177 | // Creates a reference to the inside of `DropEnum::Fancy` 178 | DropEnum::Fancy(ref fancy_field) => // 不再出错! 179 | println!("It was fancy-- {}!", fancy_field.num), 180 | } 181 | // 超出此作用域会隐式调用析构函数 `drop_struct.drop()` 182 | } 183 | ``` 184 | -------------------------------------------------------------------------------- /now/E0581.md: -------------------------------------------------------------------------------- 1 | # E0581 2 | 3 | --- 4 | 5 | In a fn type, a lifetime appears only in the return type, and not in the arguments types. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | fn main() { 11 | // Here, `'a` appears only in the return type: 12 | let x: for<'a> fn() -> &'a i32; 13 | } 14 | ``` 15 | 16 | To fix this issue, either use the lifetime in the arguments, or use 'static. Example: 17 | 18 | ```rust 19 | fn main() { 20 | // Here, `'a` appears only in the return type: 21 | let x: for<'a> fn(&'a i32) -> &'a i32; 22 | let y: fn() -> &'static i32; 23 | } 24 | ``` 25 | 26 | Note: The examples above used to be (erroneously) accepted by the compiler, but this was since corrected. See [issue #33685](https://github.com/rust-lang/rust/issues/33685) for more details. 27 | 28 | # E0581 29 | 30 | --- 31 | 32 | 在fn类型中,生命周期只出现在返回类型中,而不在参数类型中。错误代码如下: 33 | 34 | 35 | ```rust 36 | fn main() { 37 | // 这里,`'a` 仅出现在返回类型中: 38 | let x: for<'a> fn() -> &'a i32; 39 | } 40 | ``` 41 | 42 | 要解决此问题,要么在参数中使用生命周期,要么使用'static。比如: 43 | 44 | 45 | ```rust 46 | fn main() { 47 | let x: for<'a> fn(&'a i32) -> &'a i32; 48 | let y: fn() -> &'static i32; 49 | } 50 | ``` 51 | 52 | 注意:上面的错误示例曾经被编译器所接受,但是现在已经更正。参见[issue #33685](https://github.com/rust-lang/rust/issues/33685)查看更多信息。 53 | -------------------------------------------------------------------------------- /now/E0582.md: -------------------------------------------------------------------------------- 1 | # E0582 2 | 3 | --- 4 | 5 | A lifetime appears only in an associated-type binding, and not in the input types to the trait. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | 11 | fn bar(t: F) 12 | // No type can satisfy this requirement, since `'a` does not 13 | // appear in any of the input types (here, `i32`): 14 | where F: for<'a> Fn(i32) -> Option<&'a i32> 15 | { 16 | } 17 | 18 | fn main() { } 19 | 20 | ``` 21 | 22 | 23 | To fix this issue, either use the lifetime in the inputs, or use 'static. Example: 24 | 25 | 26 | ```rust 27 | 28 | fn bar(t: F, u: G) 29 | where F: for<'a> Fn(&'a i32) -> Option<&'a i32>, 30 | G: Fn(i32) -> Option<&'static i32>, 31 | { 32 | } 33 | 34 | fn main() { } 35 | ``` 36 | 37 | 38 | Note: The examples above used to be (erroneously) accepted by the compiler, but this was since corrected. See [issue #33685](https://github.com/rust-lang/rust/issues/33685) for more details. 39 | 40 | # E0582 41 | 42 | --- 43 | 44 | 生命周期仅出现在关联类型绑定中,并没有在trait输入类型中。 45 | 46 | 错误代码示例: 47 | 48 | ```rust 49 | 50 | fn bar(t: F) 51 | // 没有类型匹配此需求,因为`'a`没有出现在任何输入类型中(这里`i32`): 52 | where F: for<'a> Fn(i32) -> Option<&'a i32> 53 | { 54 | } 55 | 56 | fn main() { } 57 | 58 | ``` 59 | 60 | 要修复此问题,要么在输入中使用生命周期,要么用'static。比如: 61 | 62 | 63 | ```rust 64 | 65 | fn bar(t: F, u: G) 66 | where F: for<'a> Fn(&'a i32) -> Option<&'a i32>, 67 | G: Fn(i32) -> Option<&'static i32>, 68 | { 69 | } 70 | 71 | fn main() { } 72 | ``` 73 | 74 | 注意:上面的错误示例曾经被编译器所接受,但是现在已经更正。参见[issue #33685](https://github.com/rust-lang/rust/issues/33685)查看更多信息。 75 | -------------------------------------------------------------------------------- /now/E0597.md: -------------------------------------------------------------------------------- 1 | # E0597 2 | 3 | --- 4 | 5 | 6 | This error occurs because a borrow was made inside a variable which has a greater lifetime than the borrowed one. 7 | 8 | Example of erroneous code: 9 | 10 | ```rust 11 | struct Foo<'a> { 12 | x: Option<&'a u32>, 13 | } 14 | 15 | let mut x = Foo { x: None }; 16 | let y = 0; 17 | x.x = Some(&y); // error: `y` does not live long enough 18 | ``` 19 | 20 | In here, x is created before y and therefore has a greater lifetime. Always keep in mind that values in a scope are dropped in the opposite order they are created. So to fix the previous example, just make the y lifetime greater than the x's one: 21 | 22 | ```rust 23 | struct Foo<'a> { 24 | x: Option<&'a u32>, 25 | } 26 | 27 | let y = 0; 28 | let mut x = Foo { x: None }; 29 | x.x = Some(&y); 30 | ``` 31 | 32 | # E0597 33 | 34 | --- 35 | 36 | 发生此错误是因为在变量中使用了借用,该变量生命周期长于借用。 37 | 38 | 错误代码示例: 39 | 40 | 41 | ```rust 42 | struct Foo<'a> { 43 | x: Option<&'a u32>, 44 | } 45 | 46 | let mut x = Foo { x: None }; 47 | let y = 0; 48 | x.x = Some(&y); // error: `y`活得不够长 49 | ``` 50 | 51 | 这里x先于y被创建,因此它有更长的生命周期。请记住,作用域中的值析构顺序与其创建顺序相反。因此要修复前面的错误,只需要使y的生命周期长于x的: 52 | 53 | ```rust 54 | struct Foo<'a> { 55 | x: Option<&'a u32>, 56 | } 57 | 58 | let y = 0; 59 | let mut x = Foo { x: None }; 60 | x.x = Some(&y); 61 | ``` 62 | -------------------------------------------------------------------------------- /now/E0621.md: -------------------------------------------------------------------------------- 1 | # E0621 2 | 3 | --- 4 | 5 | This error code indicates a mismatch between the lifetimes appearing in the function signature (i.e., the parameter types and the return type) and the data-flow found in the function body. 6 | 7 | Erroneous code example: 8 | 9 | ```rust 10 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // error: explicit lifetime 11 | // required in the type of 12 | // `y` 13 | if x > y { x } else { y } 14 | } 15 | ``` 16 | 17 | In the code above, the function is returning data borrowed from either x or y, but the 'a annotation indicates that it is returning data only from x. To fix the error, the signature and the body must be made to match. Typically, this is done by updating the function signature. So, in this case, we change the type of y to &'a i32, like so: 18 | 19 | ```rust 20 | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { 21 | if x > y { x } else { y } 22 | } 23 | ``` 24 | 25 | Now the signature indicates that the function data borrowed from either x or y. Alternatively, you could change the body to not return data from y: 26 | 27 | ```rust 28 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { 29 | x 30 | } 31 | ``` 32 | 33 | # E0621 34 | 35 | --- 36 | 37 | 该错误表明,函数签名中的生命周期(即参数类型和返回类型)与函数体中的数据流不匹配。 38 | 39 | 错误代码示例: 40 | 41 | ```rust 42 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // error: 在y类型中需要显式生命周期 43 | if x > y { x } else { y } 44 | } 45 | ``` 46 | 47 | 在上面代码中,函数要么返回x的借用,要么返回y的借用,但是'a注解表明它只是从x返回数据。为了修复此错误,签名和函数体必须相匹配。一般通过修改函数签名来完成。因此,本例中,只需要修改y的类型为&'a i32, 就像这样: 48 | 49 | ```rust 50 | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { 51 | if x > y { x } else { y } 52 | } 53 | ``` 54 | 55 | 现在签名表示函数数据要么是从x要么是从y借用。或者也可以把函数体修改为不从y返回数据。 56 | 57 | 58 | ```rust 59 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { 60 | x 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /now/E0622.md: -------------------------------------------------------------------------------- 1 | # E0622 2 | An intrinsic was declared without being a function. 3 | 4 | Erroneous code example: 5 | 6 | ```rust 7 | #![feature(intrinsics)] 8 | extern "rust-intrinsic" { 9 | pub static breakpoint : unsafe extern "rust-intrinsic" fn(); 10 | // error: intrinsic must be a function 11 | } 12 | 13 | fn main() { unsafe { breakpoint(); } } 14 | ``` 15 | 16 | An intrinsic is a function available for use in a given programming language whose implementation is handled specially by the compiler. In order to fix this error, just declare a function. 17 | 18 | # E0622 19 | 一个固有函数(intrinsic)没有被声明为函数. 20 | 21 | 错误代码示例: 22 | 23 | ```rust 24 | #![feature(intrinsics)] 25 | extern "rust-intrinsic" { 26 | pub static breakpoint : unsafe extern "rust-intrinsic" fn(); 27 | // error: 内函数必须为函数 28 | } 29 | ``` 30 | 31 | 固有函数(intrinsic)是给定语言(比如Rust)内部可用的函数,其实现有编译器专门处理。为了修复该错误,只需要声明函数即可. 32 | --------------------------------------------------------------------------------