Description
The [BorrowckErrors
trait] is used to report errors from both HIR and MIR-based borrowck:
It contains various methods currently defined to take &self
:
rust/src/librustc_mir/util/borrowck_errors.rs
Lines 77 to 84 in c933440
However, it is implemented on the TyCtxt
type:
rust/src/librustc_mir/util/borrowck_errors.rs
Line 494 in c933440
This type is actually an alias for an &
-reference, so that means that the final self
winds up passing a double reference. This is not bad in and of itself, but @spastorino encountered in #48682 that the current setup causes conflicts around the tcx when using an &mut
self method. In particular, if you do something like this:
let err = self.tcx.cannot_use_while_mutably_borrowed(...);
..
this will borrow &self.tcx
for as long as err
is in use, preventing us from invoking other &mut self
methods.
For now, we worked around this problem by storing the tcx
into a local variable:
let tcx = self.tcx;
But if the methods were defined instead as fn(self)
, then it would have worked fine the original way.
Making this transformation would involve a few changes though. First off, right now the returned DiagnosticBuilder
values carry the lifetime of the incoming &self
reference. We would want to change that to the lifetime of the TyCtxt
, so we would need to modify the trait to carry a lifetime parameter:
/// This trait is expected to be implemented on a reference.
/// The `'r` is the lifetime of that reference.
trait BorrowckErrors<'cx> {
...
fn cannot_use_when_mutably_borrowed(
self, // changed to self
span: Span,
...
) -> DiagnosticBuilder<'cx> {
... // as before
}
...
}
Then it would be implememented for TyCtxt
like:
impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> { ... }
And we would have to modify the other impl like so:
impl<'a, b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> {