') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Implement `&pin` patterns and `ref pin` bindings · rust-lang/rust@5ef48ed · GitHub
Skip to content

Commit 5ef48ed

Browse files
committed
Implement &pin patterns and ref pin bindings
1 parent 6647be9 commit 5ef48ed

62 files changed

Lines changed: 886 additions & 240 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎compiler/rustc_ast/src/ast.rs‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,10 @@ impl Pat {
648648
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
649649
PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
650650
// `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
651-
PatKind::Ref(pat, mutbl) => {
652-
pat.to_ty().map(|ty| TyKind::Ref(None,MutTy{ ty,mutbl:*mutbl }))?
653-
}
651+
PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
652+
Pinnedness::Not => TyKind::Ref(None,MutTy{ ty,mutbl:*mutbl }),
653+
Pinnedness::Pinned => TyKind::PinnedRef(None,MutTy{ ty,mutbl:*mutbl }),
654+
})?,
654655
// A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
655656
// when `P` can be reparsed as a type `T`.
656657
PatKind::Slice(pats)iflet[pat] = pats.as_slice() => {
@@ -696,7 +697,7 @@ impl Pat {
696697
// Trivial wrappers over inner patterns.
697698
PatKind::Box(s)
698699
| PatKind::Deref(s)
699-
| PatKind::Ref(s, _)
700+
| PatKind::Ref(s, _, _)
700701
| PatKind::Paren(s)
701702
| PatKind::Guard(s, _) => s.walk(it),
702703

@@ -717,7 +718,7 @@ impl Pat {
717718
/// Strip off all reference patterns (`&`, `&mut`) and return the inner pattern.
718719
pubfnpeel_refs(&self) -> &Pat{
719720
letmut current = self;
720-
whileletPatKind::Ref(inner, _) = &current.kind{
721+
whileletPatKind::Ref(inner, _, _) = &current.kind{
721722
current = inner;
722723
}
723724
current
@@ -765,7 +766,9 @@ impl Pat {
765766
PatKind::Missing => unreachable!(),
766767
PatKind::Wild => Some("_".to_string()),
767768
PatKind::Ident(BindingMode::NONE, ident,None) => Some(format!("{ident}")),
768-
PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
769+
PatKind::Ref(pat, pinned, mutbl) => {
770+
pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl)))
771+
}
769772
_ => None,
770773
}
771774
}
@@ -913,7 +916,7 @@ pub enum PatKind {
913916
Deref(Box<Pat>),
914917

915918
/// A reference pattern (e.g., `&mut (a, b)`).
916-
Ref(Box<Pat>,Mutability),
919+
Ref(Box<Pat>,Pinnedness,Mutability),
917920

918921
/// A literal, const block or path.
919922
Expr(Box<Expr>),

‎compiler/rustc_ast_ir/src/lib.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,15 @@ impl Pinnedness {
317317
pubfnis_pinned(self) -> bool{
318318
matches!(self,Self::Pinned)
319319
}
320+
321+
/// Returns `""` (empty string), "mut", `"pin mut "` or `"pin const "` depending
322+
/// on the pinnedness and mutability.
323+
pubfnprefix_str(self,mutbl:Mutability) -> &'staticstr{
324+
match(self, mutbl){
325+
(Pinnedness::Pinned,Mutability::Mut) => "pin mut ",
326+
(Pinnedness::Pinned,Mutability::Not) => "pin const ",
327+
(Pinnedness::Not,Mutability::Mut) => "mut ",
328+
(Pinnedness::Not,Mutability::Not) => "",
329+
}
330+
}
320331
}

‎compiler/rustc_ast_lowering/src/pat.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
124124
PatKind::Deref(inner) => {
125125
break hir::PatKind::Deref(self.lower_pat(inner));
126126
}
127-
PatKind::Ref(inner, mutbl) => {
128-
break hir::PatKind::Ref(self.lower_pat(inner),*mutbl);
127+
PatKind::Ref(inner,pinned,mutbl) => {
128+
break hir::PatKind::Ref(self.lower_pat(inner),*pinned,*mutbl);
129129
}
130130
PatKind::Range(e1, e2,Spanned{node: end, .. }) => {
131131
break hir::PatKind::Range(

‎compiler/rustc_ast_pretty/src/pprust/state.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1807,8 +1807,14 @@ impl<'a> State<'a> {
18071807
self.print_pat(inner);
18081808
self.pclose();
18091809
}
1810-
PatKind::Ref(inner, mutbl) => {
1810+
PatKind::Ref(inner,pinned,mutbl) => {
18111811
self.word("&");
1812+
if pinned.is_pinned(){
1813+
self.word("pin ");
1814+
if mutbl.is_not(){
1815+
self.word("const ");
1816+
}
1817+
}
18121818
if mutbl.is_mut(){
18131819
self.word("mut ");
18141820
}

‎compiler/rustc_borrowck/src/diagnostics/move_errors.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
867867
for(binding_span, opt_ref_pat)in finder.ref_pat_for_binding{
868868
ifletSome(ref_pat) = opt_ref_pat
869869
&& !finder.cannot_remove.contains(&ref_pat.hir_id)
870-
&& let hir::PatKind::Ref(subpat, mutbl) = ref_pat.kind
870+
&& let hir::PatKind::Ref(subpat,pinned,mutbl) = ref_pat.kind
871871
&& letSome(ref_span) = ref_pat.span.trim_end(subpat.span)
872872
{
873+
let pinned_str = if pinned.is_pinned(){"pinned "}else{""};
873874
let mutable_str = if mutbl.is_mut(){"mutable "}else{""};
874-
let msg = format!("consider removing the {mutable_str}borrow");
875+
let msg = format!("consider removing the {pinned_str}{mutable_str}borrow");
875876
suggestions.push((ref_span, msg,"".to_string()));
876877
}else{
877878
let msg = "consider borrowing the pattern binding".to_string();

‎compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -772,11 +772,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
772772
&& letSome(hir_id) = (BindingFinder{span: pat_span }).visit_body(&body).break_value()
773773
&& let node = self.infcx.tcx.hir_node(hir_id)
774774
&& let hir::Node::LetStmt(hir::LetStmt{
775-
pat: hir::Pat{kind: hir::PatKind::Ref(_, _), .. },
775+
pat: hir::Pat{kind: hir::PatKind::Ref(_, _, _), .. },
776776
..
777777
})
778778
| hir::Node::Param(Param{
779-
pat: hir::Pat{kind: hir::PatKind::Ref(_, _), .. },
779+
pat: hir::Pat{kind: hir::PatKind::Ref(_, _, _), .. },
780780
..
781781
}) = node
782782
{
@@ -1494,7 +1494,7 @@ impl<'tcx> Visitor<'tcx> for BindingFinder {
14941494
}
14951495

14961496
fnvisit_param(&mutself,param:&'tcx hir::Param<'tcx>) -> Self::Result{
1497-
iflet hir::Pat{kind: hir::PatKind::Ref(_, _), span, .. } = param.pat
1497+
iflet hir::Pat{kind: hir::PatKind::Ref(_, _, _), span, .. } = param.pat
14981498
&& *span == self.span
14991499
{
15001500
ControlFlow::Break(param.hir_id)

‎compiler/rustc_hir/src/hir.rs‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,9 @@ impl<'hir> Pat<'hir> {
17221722
matchself.kind{
17231723
Missing => unreachable!(),
17241724
Wild | Never | Expr(_) | Range(..) | Binding(..,None) | Err(_) => true,
1725-
Box(s) | Deref(s) | Ref(s, _) | Binding(..,Some(s)) | Guard(s, _) => s.walk_short_(it),
1725+
Box(s) | Deref(s) | Ref(s, _, _) | Binding(..,Some(s)) | Guard(s, _) => {
1726+
s.walk_short_(it)
1727+
}
17261728
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
17271729
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
17281730
Slice(before, slice, after) => {
@@ -1749,7 +1751,7 @@ impl<'hir> Pat<'hir> {
17491751
usePatKind::*;
17501752
matchself.kind{
17511753
Missing | Wild | Never | Expr(_) | Range(..) | Binding(..,None) | Err(_) => {}
1752-
Box(s) | Deref(s) | Ref(s, _) | Binding(..,Some(s)) | Guard(s, _) => s.walk_(it),
1754+
Box(s) | Deref(s) | Ref(s, _, _) | Binding(..,Some(s)) | Guard(s, _) => s.walk_(it),
17531755
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
17541756
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
17551757
Slice(before, slice, after) => {
@@ -1938,7 +1940,7 @@ pub enum PatKind<'hir> {
19381940
Deref(&'hirPat<'hir>),
19391941

19401942
/// A reference pattern (e.g., `&mut (a, b)`).
1941-
Ref(&'hirPat<'hir>,Mutability),
1943+
Ref(&'hirPat<'hir>,Pinnedness,Mutability),
19421944

19431945
/// A literal, const block or path.
19441946
Expr(&'hirPatExpr<'hir>),

‎compiler/rustc_hir/src/intravisit.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
752752
}
753753
PatKind::Box(ref subpattern)
754754
| PatKind::Deref(ref subpattern)
755-
| PatKind::Ref(ref subpattern, _) => {
755+
| PatKind::Ref(ref subpattern, _, _) => {
756756
try_visit!(visitor.visit_pat(subpattern));
757757
}
758758
PatKind::Binding(_, _hir_id, ident,ref optional_subpattern) => {

‎compiler/rustc_hir_analysis/src/check/region.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ fn resolve_local<'tcx>(
593593
is_binding_pat(subpat)
594594
}
595595

596-
PatKind::Ref(_, _)
596+
PatKind::Ref(_, _, _)
597597
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
598598
| PatKind::Missing
599599
| PatKind::Wild

‎compiler/rustc_hir_pretty/src/lib.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2028,9 +2028,15 @@ impl<'a> State<'a> {
20282028
self.print_pat(inner);
20292029
self.pclose();
20302030
}
2031-
PatKind::Ref(inner, mutbl) => {
2031+
PatKind::Ref(inner,pinned,mutbl) => {
20322032
let is_range_inner = matches!(inner.kind,PatKind::Range(..));
20332033
self.word("&");
2034+
if pinned.is_pinned(){
2035+
self.word("pin ");
2036+
if mutbl.is_not(){
2037+
self.word("const ");
2038+
}
2039+
}
20342040
self.word(mutbl.prefix_str());
20352041
if is_range_inner {
20362042
self.popen();

0 commit comments

Comments
 (0)