@@ -268,16 +268,20 @@ impl NonConstOp for CellBorrow {
268268}
269269
270270#[ 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.
271274pub struct MutBorrow ( pub hir:: BorrowKind ) ;
272275
273276impl 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
281285 }
282286
283287 fn build_error ( & self , ccx : & ConstCx < ' _ , ' tcx > , span : Span ) -> DiagnosticBuilder < ' tcx > {
@@ -286,25 +290,15 @@ impl NonConstOp for MutBorrow {
286290 hir:: BorrowKind :: Ref => "" ,
287291 } ;
288292
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+
308302 if ccx. tcx . sess . teach ( & err. get_code ( ) . unwrap ( ) ) {
309303 err. note (
310304 "References in statics and constants may only refer \
@@ -321,6 +315,29 @@ impl NonConstOp for MutBorrow {
321315 }
322316}
323317
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+
324341#[ derive( Debug ) ]
325342pub struct MutDeref ;
326343impl NonConstOp for MutDeref {
@@ -329,7 +346,7 @@ impl NonConstOp for MutDeref {
329346 }
330347
331348 fn importance ( & self ) -> DiagnosticImportance {
332- // Usually a side-effect of a `MutBorrow ` somewhere.
349+ // Usually a side-effect of a `TransientMutBorrow ` somewhere.
333350 DiagnosticImportance :: Secondary
334351 }
335352
0 commit comments