@@ -517,6 +517,30 @@ macro_rules! r#try {
517
517
#[ cfg_attr( not( test) , rustc_diagnostic_item = "write_macro" ) ]
518
518
#[ allow_internal_unstable( autoref) ]
519
519
macro_rules! write {
520
+ // Retrocompat workaround to support two phased borrows:
521
+ // when `$dst` is made of chaining `.field` (or `.idx`) accesses to a local,
522
+ // it is guaranteed to be a *place* and thus there is no question of
523
+ // late-dropping anything inside it.
524
+ //
525
+ // Whilst this won't cover *all* the possible syntaxes for places (it
526
+ // won't handle places with `[…]`-indexing inside them (see
527
+ // https://github.com/rust-lang/rust/pull/100202#pullrequestreview-1064499226)
528
+ // qualified paths to `static mut`s, nor macro invocations), it ought to
529
+ // cover the vast majority of uses in practice, especially regarding
530
+ // retro-compatibility.
531
+ (
532
+ $dst_place: ident $( . $field_or_idx: tt) * ,
533
+ $( $arg: tt) *
534
+ ) => ( {
535
+ let result =
536
+ $dst_place $( . $field_or_idx ) *
537
+ . write_fmt( $crate:: format_args!( $( $arg) * ) )
538
+ ;
539
+ result
540
+ } ) ;
541
+
542
+ // default case: early-dropped `format_args!($($args)*)` while keeping
543
+ // `$dst` late-dropped.
520
544
( $dst: expr, $( $arg: tt) * ) => {
521
545
match $crate:: ops:: autoref:: autoref_mut!( $dst) {
522
546
mut _dst => {
@@ -560,6 +584,18 @@ macro_rules! writeln {
560
584
( $dst: expr $( , ) ?) => {
561
585
$crate:: write!( $dst, "\n " )
562
586
} ;
587
+
588
+ (
589
+ $dst_place: ident $( . $field_or_idx: tt) * ,
590
+ $( $arg: tt) *
591
+ ) => ( {
592
+ let result =
593
+ $dst_place $( . $field_or_idx) *
594
+ . write_fmt( $crate:: format_args_nl!( $( $arg) * ) )
595
+ ;
596
+ result
597
+ } ) ;
598
+
563
599
( $dst: expr, $( $arg: tt) * ) => {
564
600
match $crate:: ops:: autoref:: autoref_mut!( $dst) {
565
601
mut _dst => {
0 commit comments