@@ -268,16 +268,20 @@ impl NonConstOp for CellBorrow {
268
268
}
269
269
270
270
#[ derive( Debug ) ]
271
+ /// This op is for `&mut` borrows in the trailing expression of a constant
272
+ /// which uses the "enclosing scopes rule" to leak its locals into anonymous
273
+ /// static or const items.
271
274
pub struct MutBorrow ( pub hir:: BorrowKind ) ;
272
275
273
276
impl NonConstOp for MutBorrow {
274
- fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
275
- // Forbid everywhere except in const fn with a feature gate
276
- if ccx. const_kind ( ) == hir:: ConstContext :: ConstFn {
277
- Status :: Unstable ( sym:: const_mut_refs)
278
- } else {
279
- Status :: Forbidden
280
- }
277
+ fn status_in_item ( & self , _ccx : & ConstCx < ' _ , ' _ > ) -> Status {
278
+ Status :: Forbidden
279
+ }
280
+
281
+ fn importance ( & self ) -> DiagnosticImportance {
282
+ // If there were primary errors (like non-const function calls), do not emit further
283
+ // errors about mutable references.
284
+ DiagnosticImportance :: Secondary
281
285
}
282
286
283
287
fn build_error ( & self , ccx : & ConstCx < ' _ , ' tcx > , span : Span ) -> DiagnosticBuilder < ' tcx > {
@@ -286,25 +290,15 @@ impl NonConstOp for MutBorrow {
286
290
hir:: BorrowKind :: Ref => "" ,
287
291
} ;
288
292
289
- let mut err = if ccx. const_kind ( ) == hir:: ConstContext :: ConstFn {
290
- feature_err (
291
- & ccx. tcx . sess . parse_sess ,
292
- sym:: const_mut_refs,
293
- span,
294
- & format ! ( "{}mutable references are not allowed in {}s" , raw, ccx. const_kind( ) ) ,
295
- )
296
- } else {
297
- let mut err = struct_span_err ! (
298
- ccx. tcx. sess,
299
- span,
300
- E0764 ,
301
- "{}mutable references are not allowed in {}s" ,
302
- raw,
303
- ccx. const_kind( ) ,
304
- ) ;
305
- err. span_label ( span, format ! ( "`&{}mut` is only allowed in `const fn`" , raw) ) ;
306
- err
307
- } ;
293
+ let mut err = struct_span_err ! (
294
+ ccx. tcx. sess,
295
+ span,
296
+ E0764 ,
297
+ "{}mutable references are not allowed in the final value of {}s" ,
298
+ raw,
299
+ ccx. const_kind( ) ,
300
+ ) ;
301
+
308
302
if ccx. tcx . sess . teach ( & err. get_code ( ) . unwrap ( ) ) {
309
303
err. note (
310
304
"References in statics and constants may only refer \
@@ -321,6 +315,29 @@ impl NonConstOp for MutBorrow {
321
315
}
322
316
}
323
317
318
+ #[ derive( Debug ) ]
319
+ pub struct TransientMutBorrow ( pub hir:: BorrowKind ) ;
320
+
321
+ impl NonConstOp for TransientMutBorrow {
322
+ fn status_in_item ( & self , _: & ConstCx < ' _ , ' _ > ) -> Status {
323
+ Status :: Unstable ( sym:: const_mut_refs)
324
+ }
325
+
326
+ fn build_error ( & self , ccx : & ConstCx < ' _ , ' tcx > , span : Span ) -> DiagnosticBuilder < ' tcx > {
327
+ let raw = match self . 0 {
328
+ hir:: BorrowKind :: Raw => "raw " ,
329
+ hir:: BorrowKind :: Ref => "" ,
330
+ } ;
331
+
332
+ feature_err (
333
+ & ccx. tcx . sess . parse_sess ,
334
+ sym:: const_mut_refs,
335
+ span,
336
+ & format ! ( "{}mutable references are not allowed in {}s" , raw, ccx. const_kind( ) ) ,
337
+ )
338
+ }
339
+ }
340
+
324
341
#[ derive( Debug ) ]
325
342
pub struct MutDeref ;
326
343
impl NonConstOp for MutDeref {
@@ -329,7 +346,7 @@ impl NonConstOp for MutDeref {
329
346
}
330
347
331
348
fn importance ( & self ) -> DiagnosticImportance {
332
- // Usually a side-effect of a `MutBorrow ` somewhere.
349
+ // Usually a side-effect of a `TransientMutBorrow ` somewhere.
333
350
DiagnosticImportance :: Secondary
334
351
}
335
352
0 commit comments