diff options
| author | Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> | 2023-01-28 20:43:16 +0100 |
|---|---|---|
| committer | Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> | 2023-01-28 20:43:16 +0100 |
| commit | 832751fe1df232e36b283fa136b4e26475e55c00 (patch) | |
| tree | 2f4c799c8298bd01be6c026d90e5fd110197cc34 | |
| parent | 7919ef0ec5776c72dace7fec1c68551a617505ad (diff) | |
| download | rust-832751fe1df232e36b283fa136b4e26475e55c00.tar.gz rust-832751fe1df232e36b283fa136b4e26475e55c00.zip | |
Also erase substs for new infcx in pin move error
The code originally correctly erased the regions of the type it passed to the newly created infcx. But after the `fn_sig` query was made to return an `EarlyBinder<T>`, some substs that were around were substituted there without erasing their regions. They were then passed into the newly cerated infcx, which caused the ICE.
4 files changed, 46 insertions, 0 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 1011794d7b3..8c579bac7e8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1128,8 +1128,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "{place_name} {partially_str}moved due to this method call{loop_message}", ), ); + let infcx = tcx.infer_ctxt().build(); + // Erase and shadow everything that could be passed to the new infcx. let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty); + let method_substs = tcx.erase_regions(method_substs); + if let ty::Adt(def, substs) = ty.kind() && Some(def.did()) == tcx.lang_items().pin_type() && let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind() diff --git a/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.fixed b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.fixed new file mode 100644 index 00000000000..0b9a3bae961 --- /dev/null +++ b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.fixed @@ -0,0 +1,11 @@ +// run-rustfix +use std::pin::Pin; + +fn foo(_: &mut ()) {} + +fn main() { + let mut uwu = (); + let mut r = Pin::new(&mut uwu); + foo(r.as_mut().get_mut()); + foo(r.get_mut()); //~ ERROR use of moved value +} diff --git a/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.rs b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.rs new file mode 100644 index 00000000000..0e952b06ee1 --- /dev/null +++ b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.rs @@ -0,0 +1,11 @@ +// run-rustfix +use std::pin::Pin; + +fn foo(_: &mut ()) {} + +fn main() { + let mut uwu = (); + let mut r = Pin::new(&mut uwu); + foo(r.get_mut()); + foo(r.get_mut()); //~ ERROR use of moved value +} diff --git a/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr new file mode 100644 index 00000000000..7e513b73c21 --- /dev/null +++ b/tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.stderr @@ -0,0 +1,20 @@ +error[E0382]: use of moved value: `r` + --> $DIR/pin-mut-reborrow-infer-var-issue-107419.rs:10:9 + | +LL | let mut r = Pin::new(&mut uwu); + | ----- move occurs because `r` has type `Pin<&mut ()>`, which does not implement the `Copy` trait +LL | foo(r.get_mut()); + | --------- `r` moved due to this method call +LL | foo(r.get_mut()); + | ^ value used here after move + | +note: `Pin::<&'a mut T>::get_mut` takes ownership of the receiver `self`, which moves `r` + --> $SRC_DIR/core/src/pin.rs:LL:COL +help: consider reborrowing the `Pin` instead of moving it + | +LL | foo(r.as_mut().get_mut()); + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. |
