about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs5
-rw-r--r--tests/ui/borrowck/span-semicolon-issue-139049.fixed59
-rw-r--r--tests/ui/borrowck/span-semicolon-issue-139049.rs59
-rw-r--r--tests/ui/borrowck/span-semicolon-issue-139049.stderr62
4 files changed, 65 insertions, 120 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index c4b0f503664..095c0df98ac 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -342,10 +342,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
                                 }
                             }
                         } else if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
-                            let sp = info
-                                .span
-                                .find_ancestor_in_same_ctxt(local_decl.source_info.span)
-                                .unwrap_or(info.span);
+                            let sp = info.span.find_oldest_ancestor_in_same_ctxt();
                             if info.tail_result_is_ignored {
                                 // #85581: If the first mutable borrow's scope contains
                                 // the second borrow, this suggestion isn't helpful.
diff --git a/tests/ui/borrowck/span-semicolon-issue-139049.fixed b/tests/ui/borrowck/span-semicolon-issue-139049.fixed
index 0b263b22296..c01d1242dd7 100644
--- a/tests/ui/borrowck/span-semicolon-issue-139049.fixed
+++ b/tests/ui/borrowck/span-semicolon-issue-139049.fixed
@@ -1,52 +1,25 @@
-// Make sure the generated suggestion suggest editing the user
-// code instead of the std macro implementation
+// Make sure the generated suggestion suggest editing the user code instead of
+// the macro implementation (which might come from an external crate).
+// issue: <https://github.com/rust-lang/rust/issues/139049>
 
 //@ run-rustfix
 
 #![allow(dead_code)]
 
-use std::fmt::{self, Display};
-
-struct Mutex;
-
-impl Mutex {
-    fn lock(&self) -> MutexGuard<'_> {
-        MutexGuard(self)
-    }
-}
-
-struct MutexGuard<'a>(&'a Mutex);
-
-impl<'a> Drop for MutexGuard<'a> {
-    fn drop(&mut self) {}
-}
-
-struct Out;
-
-impl Out {
-    fn write_fmt(&self, _args: fmt::Arguments) {}
-}
-
-impl<'a> Display for MutexGuard<'a> {
-    fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
-        Ok(())
-    }
-}
+// You could assume that this comes from an extern crate (it doesn't
+// because an aux crate would be overkill for this test).
+macro_rules! perform { ($e:expr) => { D(&$e).end() } }
+//~^ ERROR does not live long enough
+//~| ERROR does not live long enough
 
 fn main() {
-    let _write = {
-        let mutex = Mutex;
-        write!(Out, "{}", mutex.lock());
-        //~^ ERROR `mutex` does not live long enough
-        //~| SUGGESTION ;
-    };
-
-    let _write = {
-        use std::io::Write as _;
+    { let l = (); perform!(l); };
+    //~^ SUGGESTION ;
 
-        let mutex = Mutex;
-        let x = write!(std::io::stdout(), "{}", mutex.lock()); x
-        //~^ ERROR `mutex` does not live long enough
-        //~| SUGGESTION let x
-    };
+    let _x = { let l = (); let x = perform!(l); x };
+    //~^ SUGGESTION let x
 }
+
+struct D<T>(T);
+impl<T> Drop for D<T> { fn drop(&mut self) {} }
+impl<T> D<T> { fn end(&self) -> String { String::new() } }
diff --git a/tests/ui/borrowck/span-semicolon-issue-139049.rs b/tests/ui/borrowck/span-semicolon-issue-139049.rs
index a92742ac94b..43558756c71 100644
--- a/tests/ui/borrowck/span-semicolon-issue-139049.rs
+++ b/tests/ui/borrowck/span-semicolon-issue-139049.rs
@@ -1,52 +1,25 @@
-// Make sure the generated suggestion suggest editing the user
-// code instead of the std macro implementation
+// Make sure the generated suggestion suggest editing the user code instead of
+// the macro implementation (which might come from an external crate).
+// issue: <https://github.com/rust-lang/rust/issues/139049>
 
 //@ run-rustfix
 
 #![allow(dead_code)]
 
-use std::fmt::{self, Display};
-
-struct Mutex;
-
-impl Mutex {
-    fn lock(&self) -> MutexGuard<'_> {
-        MutexGuard(self)
-    }
-}
-
-struct MutexGuard<'a>(&'a Mutex);
-
-impl<'a> Drop for MutexGuard<'a> {
-    fn drop(&mut self) {}
-}
-
-struct Out;
-
-impl Out {
-    fn write_fmt(&self, _args: fmt::Arguments) {}
-}
-
-impl<'a> Display for MutexGuard<'a> {
-    fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
-        Ok(())
-    }
-}
+// You could assume that this comes from an extern crate (it doesn't
+// because an aux crate would be overkill for this test).
+macro_rules! perform { ($e:expr) => { D(&$e).end() } }
+//~^ ERROR does not live long enough
+//~| ERROR does not live long enough
 
 fn main() {
-    let _write = {
-        let mutex = Mutex;
-        write!(Out, "{}", mutex.lock())
-        //~^ ERROR `mutex` does not live long enough
-        //~| SUGGESTION ;
-    };
-
-    let _write = {
-        use std::io::Write as _;
+    { let l = (); perform!(l) };
+    //~^ SUGGESTION ;
 
-        let mutex = Mutex;
-        write!(std::io::stdout(), "{}", mutex.lock())
-        //~^ ERROR `mutex` does not live long enough
-        //~| SUGGESTION let x
-    };
+    let _x = { let l = (); perform!(l) };
+    //~^ SUGGESTION let x
 }
+
+struct D<T>(T);
+impl<T> Drop for D<T> { fn drop(&mut self) {} }
+impl<T> D<T> { fn end(&self) -> String { String::new() } }
diff --git a/tests/ui/borrowck/span-semicolon-issue-139049.stderr b/tests/ui/borrowck/span-semicolon-issue-139049.stderr
index 123bdf4bc67..8d2de67382b 100644
--- a/tests/ui/borrowck/span-semicolon-issue-139049.stderr
+++ b/tests/ui/borrowck/span-semicolon-issue-139049.stderr
@@ -1,46 +1,48 @@
-error[E0597]: `mutex` does not live long enough
-  --> $DIR/span-semicolon-issue-139049.rs:39:27
+error[E0597]: `l` does not live long enough
+  --> $DIR/span-semicolon-issue-139049.rs:11:41
    |
-LL |         let mutex = Mutex;
-   |             ----- binding `mutex` declared here
-LL |         write!(Out, "{}", mutex.lock())
-   |                           ^^^^^-------
-   |                           |
-   |                           borrowed value does not live long enough
-   |                           a temporary with access to the borrow is created here ...
+LL | macro_rules! perform { ($e:expr) => { D(&$e).end() } }
+   |                                       --^^^-
+   |                                       | |
+   |                                       | borrowed value does not live long enough
+   |                                       a temporary with access to the borrow is created here ...
 ...
-LL |     };
-   |     -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
-   |     |
-   |     `mutex` dropped here while still borrowed
+LL |     { let l = (); perform!(l) };
+   |           -       ----------- -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |           |       |           |
+   |           |       |           `l` dropped here while still borrowed
+   |           |       in this macro invocation
+   |           binding `l` declared here
    |
+   = note: this error originates in the macro `perform` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
-LL |         write!(Out, "{}", mutex.lock());
-   |                                        +
+LL |     { let l = (); perform!(l); };
+   |                              +
 
-error[E0597]: `mutex` does not live long enough
-  --> $DIR/span-semicolon-issue-139049.rs:48:41
+error[E0597]: `l` does not live long enough
+  --> $DIR/span-semicolon-issue-139049.rs:11:41
    |
-LL |         let mutex = Mutex;
-   |             ----- binding `mutex` declared here
-LL |         write!(std::io::stdout(), "{}", mutex.lock())
-   |                                         ^^^^^-------
-   |                                         |
-   |                                         borrowed value does not live long enough
-   |                                         a temporary with access to the borrow is created here ...
+LL | macro_rules! perform { ($e:expr) => { D(&$e).end() } }
+   |                                       --^^^-
+   |                                       | |
+   |                                       | borrowed value does not live long enough
+   |                                       a temporary with access to the borrow is created here ...
 ...
-LL |     };
-   |     -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
-   |     |
-   |     `mutex` dropped here while still borrowed
+LL |     let _x = { let l = (); perform!(l) };
+   |                    -       ----------- -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                    |       |           |
+   |                    |       |           `l` dropped here while still borrowed
+   |                    |       in this macro invocation
+   |                    binding `l` declared here
    |
    = note: the temporary is part of an expression at the end of a block;
            consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
+   = note: this error originates in the macro `perform` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
    |
-LL |         let x = write!(std::io::stdout(), "{}", mutex.lock()); x
-   |         +++++++                                              +++
+LL |     let _x = { let l = (); let x = perform!(l); x };
+   |                            +++++++            +++
 
 error: aborting due to 2 previous errors