@@ -268,43 +268,41 @@ 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
277
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
278
+ match ccx. const_kind ( ) {
279
+ // Mutable statics can handle mutable references in their final value
280
+ hir:: ConstContext :: Static ( hir:: Mutability :: Mut ) => Status :: Allowed ,
281
+ _ => Status :: Forbidden ,
280
282
}
281
283
}
282
284
285
+ fn importance ( & self ) -> DiagnosticImportance {
286
+ // If there were primary errors (like non-const function calls), do not emit further
287
+ // errors about mutable references.
288
+ DiagnosticImportance :: Secondary
289
+ }
290
+
283
291
fn build_error ( & self , ccx : & ConstCx < ' _ , ' tcx > , span : Span ) -> DiagnosticBuilder < ' tcx > {
284
292
let raw = match self . 0 {
285
293
hir:: BorrowKind :: Raw => "raw " ,
286
294
hir:: BorrowKind :: Ref => "" ,
287
295
} ;
288
296
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
- } ;
297
+ let mut err = struct_span_err ! (
298
+ ccx. tcx. sess,
299
+ span,
300
+ E0764 ,
301
+ "{}mutable references are not allowed in final value of {}s" ,
302
+ raw,
303
+ ccx. const_kind( ) ,
304
+ ) ;
305
+
308
306
if ccx. tcx . sess . teach ( & err. get_code ( ) . unwrap ( ) ) {
309
307
err. note (
310
308
"References in statics and constants may only refer \
@@ -321,6 +319,29 @@ impl NonConstOp for MutBorrow {
321
319
}
322
320
}
323
321
322
+ #[ derive( Debug ) ]
323
+ pub struct TransientMutBorrow ( pub hir:: BorrowKind ) ;
324
+
325
+ impl NonConstOp for TransientMutBorrow {
326
+ fn status_in_item ( & self , _: & ConstCx < ' _ , ' _ > ) -> Status {
327
+ Status :: Unstable ( sym:: const_mut_refs)
328
+ }
329
+
330
+ fn build_error ( & self , ccx : & ConstCx < ' _ , ' tcx > , span : Span ) -> DiagnosticBuilder < ' tcx > {
331
+ let raw = match self . 0 {
332
+ hir:: BorrowKind :: Raw => "raw " ,
333
+ hir:: BorrowKind :: Ref => "" ,
334
+ } ;
335
+
336
+ feature_err (
337
+ & ccx. tcx . sess . parse_sess ,
338
+ sym:: const_mut_refs,
339
+ span,
340
+ & format ! ( "{}mutable references are not allowed in {}s" , raw, ccx. const_kind( ) ) ,
341
+ )
342
+ }
343
+ }
344
+
324
345
#[ derive( Debug ) ]
325
346
pub struct MutDeref ;
326
347
impl NonConstOp for MutDeref {
@@ -329,7 +350,7 @@ impl NonConstOp for MutDeref {
329
350
}
330
351
331
352
fn importance ( & self ) -> DiagnosticImportance {
332
- // Usually a side-effect of a `MutBorrow ` somewhere.
353
+ // Usually a side-effect of a `TransientMutBorrow ` somewhere.
333
354
DiagnosticImportance :: Secondary
334
355
}
335
356
0 commit comments