diff options
| author | dianne <diannes.gm@gmail.com> | 2025-04-16 18:41:52 -0700 |
|---|---|---|
| committer | dianne <diannes.gm@gmail.com> | 2025-04-24 14:25:27 -0700 |
| commit | 0eb3b110f0b14b21de2e7c283ea21bc86e0d311d (patch) | |
| tree | 5b2040e453a20c590afc7998d12aec5feb882139 /compiler/rustc_middle/src | |
| parent | 64c8d5d7f53d7ca053335eeb3ef5756c1bbdb5f2 (diff) | |
| download | rust-0eb3b110f0b14b21de2e7c283ea21bc86e0d311d.tar.gz rust-0eb3b110f0b14b21de2e7c283ea21bc86e0d311d.zip | |
lower deref patterns on boxes using built-in derefs
This allows deref patterns to move out of boxes. Implementation-wise, I've opted to put the information of whether a deref pattern uses a built-in deref or a method call in the THIR. It'd be a bit less code to check `.is_box()` everywhere, but I think this way feels more robust (and we don't have a `mutability` field in the THIR that we ignore when the smart pointer's a box). I'm not sure about the naming (or using `ByRef`), though.
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/typeck_results.rs | 15 |
2 files changed, 21 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index c168142fb1e..086ec529f33 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -799,7 +799,12 @@ pub enum PatKind<'tcx> { /// Deref pattern, written `box P` for now. DerefPattern { subpattern: Box<Pat<'tcx>>, - mutability: hir::Mutability, + /// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or + /// `DerefMut::deref_mut`, and if so, which. This is `ByRef::No` for deref patterns on + /// boxes; they are lowered using a built-in deref rather than a method call, thus they + /// don't borrow the scrutinee. + #[type_visitable(ignore)] + borrow: ByRef, }, /// One of the following: diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 4c5c669771f..8c5827d36df 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -475,6 +475,21 @@ impl<'tcx> TypeckResults<'tcx> { has_ref_mut } + /// How should a deref pattern find the place for its inner pattern to match on? + /// + /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner + /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`. + /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee; + /// in this case, we return `ByRef::No`. + pub fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: &hir::Pat<'_>) -> ByRef { + if pointer_ty.is_box() { + ByRef::No + } else { + let mutable = self.pat_has_ref_mut_binding(inner); + ByRef::Yes(if mutable { Mutability::Mut } else { Mutability::Not }) + } + } + /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured /// by the closure. pub fn closure_min_captures_flattened( |
