diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 4be22020ba153..ddd54f7c2089d 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -192,9 +192,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_pat(&mut self, pat: &'hir Pat<'hir>) { - let node = - if let PatKind::Binding(..) = pat.kind { Node::Binding(pat) } else { Node::Pat(pat) }; - self.insert(pat.span, pat.hir_id, node); + self.insert(pat.span, pat.hir_id, Node::Pat(pat)); self.with_parent(pat.hir_id, |this| { intravisit::walk_pat(this, pat); diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 49b24a05071b2..3c5dd32d2816e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -362,7 +362,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar_hir_id = captured_place.get_root_variable(); - if let Some(Node::Binding(pat)) = self.infcx.tcx.hir().find(upvar_hir_id) + if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id) && let hir::PatKind::Binding( hir::BindingAnnotation::Unannotated, _, diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 905ab6cb578fc..847694cbd10cb 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -244,7 +244,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // for a generator). let var_hir_id = captured_place.get_root_variable(); let node = self.ecx.tcx.hir().get(var_hir_id); - if let hir::Node::Binding(pat) = node { + if let hir::Node::Pat(pat) = node { if let hir::PatKind::Binding(_, _, ident, _) = pat.kind { name = Some(ident.name); } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 78b0892b3bc17..9c42f6f26fc9e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1447,7 +1447,7 @@ impl HandlerInner { self.flags.treat_err_as_bug.map(|c| c.get()).unwrap_or(0), ) { (1, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"), - (0, _) | (1, _) => {} + (0 | 1, _) => {} (count, as_bug) => panic!( "aborting after {} errors due to `-Z treat-err-as-bug={}`", count, as_bug, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a7fc59255d79a..a2ef158ce8d32 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3326,7 +3326,6 @@ pub enum Node<'hir> { Ty(&'hir Ty<'hir>), TypeBinding(&'hir TypeBinding<'hir>), TraitRef(&'hir TraitRef<'hir>), - Binding(&'hir Pat<'hir>), Pat(&'hir Pat<'hir>), Arm(&'hir Arm<'hir>), Block(&'hir Block<'hir>), @@ -3378,7 +3377,6 @@ impl<'hir> Node<'hir> { | Node::Block(..) | Node::Ctor(..) | Node::Pat(..) - | Node::Binding(..) | Node::Arm(..) | Node::Local(..) | Node::Crate(..) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 7bf91df9f760b..fd843b0c403a6 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -87,7 +87,7 @@ impl<'a> State<'a> { Node::Ty(a) => self.print_type(&a), Node::TypeBinding(a) => self.print_type_binding(&a), Node::TraitRef(a) => self.print_trait_ref(&a), - Node::Binding(a) | Node::Pat(a) => self.print_pat(&a), + Node::Pat(a) => self.print_pat(&a), Node::Arm(a) => self.print_arm(&a), Node::Infer(_) => self.word("_"), Node::Block(a) => { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index a27b8470e9573..72077e7301359 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -302,7 +302,6 @@ impl<'hir> Map<'hir> { | Node::Infer(_) | Node::TraitRef(_) | Node::Pat(_) - | Node::Binding(_) | Node::Local(_) | Node::Param(_) | Node::Arm(_) @@ -901,7 +900,7 @@ impl<'hir> Map<'hir> { #[inline] fn opt_ident(self, id: HirId) -> Option { match self.get(id) { - Node::Binding(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), + Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::opt_span`. Node::Ctor(..) => match self.find(self.get_parent_node(id))? { @@ -969,7 +968,6 @@ impl<'hir> Map<'hir> { Node::Ty(ty) => ty.span, Node::TypeBinding(tb) => tb.span, Node::TraitRef(tr) => tr.path.span, - Node::Binding(pat) => pat.span, Node::Pat(pat) => pat.span, Node::Arm(arm) => arm.span, Node::Block(block) => block.span, @@ -1203,7 +1201,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { Some(Node::Ty(_)) => node_str("type"), Some(Node::TypeBinding(_)) => node_str("type binding"), Some(Node::TraitRef(_)) => node_str("trait ref"), - Some(Node::Binding(_)) => node_str("local"), Some(Node::Pat(_)) => node_str("pat"), Some(Node::Param(_)) => node_str("param"), Some(Node::Arm(_)) => node_str("arm"), diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index cdacf3ad892e0..e27761381f633 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -997,7 +997,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { continue; }; let pat = match tcx.hir().get(arg.pat.hir_id) { - Node::Pat(pat) | Node::Binding(pat) => pat, + Node::Pat(pat) => pat, node => bug!("pattern became {:?}", node), }; let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index d853a5e9ee797..2645155adc67b 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -101,7 +101,7 @@ impl<'tcx> Cx<'tcx> { #[tracing::instrument(level = "debug", skip(self))] pub(crate) fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> { let p = match self.tcx.hir().get(p.hir_id) { - Node::Pat(p) | Node::Binding(p) => p, + Node::Pat(p) => p, node => bug!("pattern became {:?}", node), }; pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p) diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 99f38b3222dca..0a0c674d179e9 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -623,9 +623,9 @@ impl<'tcx> SaveContext<'tcx> { } }, - Node::Binding(&hir::Pat { - kind: hir::PatKind::Binding(_, canonical_id, ..), .. - }) => Res::Local(canonical_id), + Node::Pat(&hir::Pat { kind: hir::PatKind::Binding(_, canonical_id, ..), .. }) => { + Res::Local(canonical_id) + } _ => Res::Err, } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 961bbc426613c..53ca027bb57f5 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -223,7 +223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, hir::Path { res: hir::def::Res::Local(hir_id), .. }, )) => { - if let Some(hir::Node::Binding(pat)) = self.tcx.hir().find(*hir_id) { + if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) { let parent = self.tcx.hir().get_parent_node(pat.hir_id); primary_span = pat.span; secondary_span = pat.span; diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs index dbc309b29ff11..365ff429243f1 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs @@ -251,7 +251,6 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { | hir::Node::Ty(..) | hir::Node::TypeBinding(..) | hir::Node::TraitRef(..) - | hir::Node::Binding(..) | hir::Node::Pat(..) | hir::Node::Arm(..) | hir::Node::Local(..) diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs new file mode 100644 index 0000000000000..a7519ab5ab633 --- /dev/null +++ b/library/core/src/sync/exclusive.rs @@ -0,0 +1,173 @@ +//! Defines [`Exclusive`]. + +use core::fmt; +use core::future::Future; +use core::pin::Pin; +use core::task::{Context, Poll}; + +/// `Exclusive` provides only _mutable_ access, also referred to as _exclusive_ +/// access to the underlying value. It provides no _immutable_, or _shared_ +/// access to the underlying value. +/// +/// While this may seem not very useful, it allows `Exclusive` to _unconditionally_ +/// implement [`Sync`]. Indeed, the safety requirements of `Sync` state that for `Exclusive` +/// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound +/// for `&Exclusive` to cross thread boundaries. By design, a `&Exclusive` has no API +/// whatsoever, making it useless, thus harmless, thus memory safe. +/// +/// Certain constructs like [`Future`]s can only be used with _exclusive_ access, +/// and are often `Send` but not `Sync`, so `Exclusive` can be used as hint to the +/// rust compiler that something is `Sync` in practice. +/// +/// ## Examples +/// Using a non-`Sync` future prevents the wrapping struct from being `Sync` +/// ```compile_fail +/// use core::cell::Cell; +/// +/// async fn other() {} +/// fn assert_sync(t: T) {} +/// struct State { +/// future: F +/// } +/// +/// assert_sync(State { +/// future: async { +/// let cell = Cell::new(1); +/// let cell_ref = &cell; +/// other().await; +/// let value = cell_ref.get(); +/// } +/// }); +/// ``` +/// +/// `Exclusive` ensures the struct is `Sync` without stripping the future of its +/// functionality. +/// ``` +/// #![feature(exclusive_wrapper)] +/// use core::cell::Cell; +/// use core::sync::Exclusive; +/// +/// async fn other() {} +/// fn assert_sync(t: T) {} +/// struct State { +/// future: Exclusive +/// } +/// +/// assert_sync(State { +/// future: Exclusive::new(async { +/// let cell = Cell::new(1); +/// let cell_ref = &cell; +/// other().await; +/// let value = cell_ref.get(); +/// }) +/// }); +/// ``` +/// +/// ## Parallels with a mutex +/// In some sense, `Exclusive` can be thought of as a _compile-time_ version of +/// a mutex, as the borrow-checker guarantees that only one `&mut` can exist +/// for any value. This is a parallel with the fact that +/// `&` and `&mut` references together can be thought of as a _compile-time_ +/// version of a read-write lock. +/// +/// +/// [`Sync`]: core::marker::Sync +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[doc(alias = "SyncWrapper")] +#[doc(alias = "SyncCell")] +#[doc(alias = "Unique")] +// `Exclusive` can't have `PartialOrd`, `Clone`, etc. impls as they would +// use `&` access to the inner value, violating the `Sync` impl's safety +// requirements. +#[derive(Default)] +#[repr(transparent)] +pub struct Exclusive { + inner: T, +} + +// See `Exclusive`'s docs for justification. +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +unsafe impl Sync for Exclusive {} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl fmt::Debug for Exclusive { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_struct("Exclusive").finish_non_exhaustive() + } +} + +impl Exclusive { + /// Wrap a value in an `Exclusive` + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + pub const fn new(t: T) -> Self { + Self { inner: t } + } + + /// Unwrap the value contained in the `Exclusive` + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + pub const fn into_inner(self) -> T { + self.inner + } +} + +impl Exclusive { + /// Get exclusive access to the underlying value. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + pub const fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Get pinned exclusive access to the underlying value. + /// + /// `Exclusive` is considered to _structurally pin_ the underlying + /// value, which means _unpinned_ `Exclusive`s can produce _unpinned_ + /// access to the underlying value, but _pinned_ `Exclusive`s only + /// produce _pinned_ access to the underlying value. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + pub const fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> { + // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned + // `Pin::map_unchecked_mut` is not const, so we do this conversion manually + unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } + } + + /// Build a _mutable_ references to an `Exclusive` from + /// a _mutable_ reference to a `T`. This allows you to skip + /// building an `Exclusive` with [`Exclusive::new`]. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + pub const fn from_mut(r: &'_ mut T) -> &'_ mut Exclusive { + // SAFETY: repr is ≥ C, so refs have the same layout; and `Exclusive` properties are `&mut`-agnostic + unsafe { &mut *(r as *mut T as *mut Exclusive) } + } + + /// Build a _pinned mutable_ references to an `Exclusive` from + /// a _pinned mutable_ reference to a `T`. This allows you to skip + /// building an `Exclusive` with [`Exclusive::new`]. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + pub const fn from_pin_mut(r: Pin<&'_ mut T>) -> Pin<&'_ mut Exclusive> { + // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned + // `Pin::map_unchecked_mut` is not const, so we do this conversion manually + unsafe { Pin::new_unchecked(Self::from_mut(r.get_unchecked_mut())) } + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl From for Exclusive { + fn from(t: T) -> Self { + Self::new(t) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl Future for Exclusive { + type Output = T::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.get_pin_mut().poll(cx) + } +} diff --git a/library/core/src/sync/mod.rs b/library/core/src/sync/mod.rs index b635bae0a47b4..4365e4cb250ca 100644 --- a/library/core/src/sync/mod.rs +++ b/library/core/src/sync/mod.rs @@ -3,3 +3,6 @@ #![stable(feature = "rust1", since = "1.0.0")] pub mod atomic; +mod exclusive; +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +pub use exclusive::Exclusive; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 65b8df4299663..ba76ee31b42dd 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -270,6 +270,7 @@ #![feature(duration_checked_float)] #![feature(duration_constants)] #![feature(exact_size_is_empty)] +#![feature(exclusive_wrapper)] #![feature(extend_one)] #![feature(float_minimum_maximum)] #![feature(hasher_prefixfree_extras)] diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 5fc18fda6a83b..7b507a169b395 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -155,6 +155,8 @@ pub use alloc_crate::sync::{Arc, Weak}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::sync::atomic; +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +pub use core::sync::Exclusive; #[stable(feature = "rust1", since = "1.0.0")] pub use self::barrier::{Barrier, BarrierWaitResult}; diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 0a6a7cfe976cc..c70ac8c9806d6 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -159,6 +159,7 @@ use crate::cell::UnsafeCell; use crate::ffi::{CStr, CString}; use crate::fmt; use crate::io; +use crate::marker::PhantomData; use crate::mem; use crate::num::NonZeroU64; use crate::num::NonZeroUsize; @@ -462,7 +463,7 @@ impl Builder { unsafe fn spawn_unchecked_<'a, 'scope, F, T>( self, f: F, - scope_data: Option<&'scope scoped::ScopeData>, + scope_data: Option>, ) -> io::Result> where F: FnOnce() -> T, @@ -479,8 +480,11 @@ impl Builder { })); let their_thread = my_thread.clone(); - let my_packet: Arc> = - Arc::new(Packet { scope: scope_data, result: UnsafeCell::new(None) }); + let my_packet: Arc> = Arc::new(Packet { + scope: scope_data, + result: UnsafeCell::new(None), + _marker: PhantomData, + }); let their_packet = my_packet.clone(); let output_capture = crate::io::set_output_capture(None); @@ -507,7 +511,7 @@ impl Builder { unsafe { *their_packet.result.get() = Some(try_result) }; }; - if let Some(scope_data) = scope_data { + if let Some(scope_data) = &my_packet.scope { scope_data.increment_num_running_threads(); } @@ -1298,8 +1302,9 @@ pub type Result = crate::result::Result>; // An Arc to the packet is stored into a `JoinInner` which in turns is placed // in `JoinHandle`. struct Packet<'scope, T> { - scope: Option<&'scope scoped::ScopeData>, + scope: Option>, result: UnsafeCell>>, + _marker: PhantomData>, } // Due to the usage of `UnsafeCell` we need to manually implement Sync. @@ -1330,7 +1335,7 @@ impl<'scope, T> Drop for Packet<'scope, T> { rtabort!("thread result panicked on drop"); } // Book-keeping so the scope knows when it's done. - if let Some(scope) = self.scope { + if let Some(scope) = &self.scope { // Now that there will be no more user code running on this thread // that can use 'scope, mark the thread as 'finished'. // It's important we only do this after the `result` has been dropped, diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index a387a09dc8b15..e6dbf35bd0286 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -11,7 +11,7 @@ use crate::sync::Arc; /// See [`scope`] for details. #[stable(feature = "scoped_threads", since = "1.63.0")] pub struct Scope<'scope, 'env: 'scope> { - data: ScopeData, + data: Arc, /// Invariance over 'scope, to make sure 'scope cannot shrink, /// which is necessary for soundness. /// @@ -130,12 +130,14 @@ pub fn scope<'env, F, T>(f: F) -> T where F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T, { + // We put the `ScopeData` into an `Arc` so that other threads can finish their + // `decrement_num_running_threads` even after this function returns. let scope = Scope { - data: ScopeData { + data: Arc::new(ScopeData { num_running_threads: AtomicUsize::new(0), main_thread: current(), a_thread_panicked: AtomicBool::new(false), - }, + }), env: PhantomData, scope: PhantomData, }; @@ -250,7 +252,7 @@ impl Builder { F: FnOnce() -> T + Send + 'scope, T: Send + 'scope, { - Ok(ScopedJoinHandle(unsafe { self.spawn_unchecked_(f, Some(&scope.data)) }?)) + Ok(ScopedJoinHandle(unsafe { self.spawn_unchecked_(f, Some(scope.data.clone())) }?)) } } diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs new file mode 100644 index 0000000000000..828c871143ad5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-72793.rs @@ -0,0 +1,25 @@ +// check-pass +// compile-flags: -Zmir-opt-level=3 + +#![feature(type_alias_impl_trait)] + +trait T { type Item; } + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +fn filter_positive<'a>() -> Alias<'a> { + &S +} + +fn with_positive(fun: impl Fn(Alias<'_>)) { + fun(filter_positive()); +} + +fn main() { + with_positive(|_| ()); +} diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 9d21dd71e0e8d..82c15ae313f27 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::contains_ty; use rustc_hir::intravisit; -use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node}; +use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; @@ -131,7 +131,10 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { // TODO: Replace with Map::is_argument(..) when it's fixed fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool { match map.find(id) { - Some(Node::Binding(_)) => (), + Some(Node::Pat(Pat { + kind: PatKind::Binding(..), + .. + })) => (), _ => return false, } @@ -143,15 +146,6 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { if cmt.place.projections.is_empty() { if let PlaceBase::Local(lid) = cmt.place.base { self.set.remove(&lid); - let map = &self.cx.tcx.hir(); - if let Some(Node::Binding(_)) = map.find(cmt.hir_id) { - if self.set.contains(&lid) { - // let y = x where x is known - // remove x, insert y - self.set.insert(cmt.hir_id); - self.set.remove(&lid); - } - } } } } diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs index 12d636cf41014..5bf4313b41a49 100644 --- a/src/tools/clippy/clippy_lints/src/explicit_write.rs +++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs @@ -125,7 +125,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>) // Find id of the local that expr_end_of_block resolves to if let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind; if let Res::Local(expr_res) = expr_path.res; - if let Some(Node::Binding(res_pat)) = cx.tcx.hir().find(expr_res); + if let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res); // Find id of the local we found in the block if let PatKind::Binding(BindingAnnotation::Unannotated, local_hir_id, _ident, None) = local.pat.kind; diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index d20df83045589..aedf3810b23e9 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -43,7 +43,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option) { fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option { if_chain! { if let Some(hir_id) = path_to_local(bound); - if let Node::Binding(pat) = cx.tcx.hir().get(hir_id); + if let Node::Pat(pat) = cx.tcx.hir().get(hir_id); if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind; then { return Some(hir_id); diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs index e048d744fc3ba..1439f1f4c75d5 100644 --- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs +++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs @@ -63,7 +63,7 @@ pub(super) fn check<'tcx>( Res::Local(hir_id) => { let node = cx.tcx.hir().get(hir_id); if_chain! { - if let Node::Binding(pat) = node; + if let Node::Pat(pat) = node; if let PatKind::Binding(bind_ann, ..) = pat.kind; if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable); let parent_node = cx.tcx.hir().get_parent_node(hir_id); diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs index f5410c7fd7fc8..43e9451f7d37e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs @@ -22,7 +22,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr |diag| { if_chain! { if let Some(id) = path_to_local(recv); - if let Node::Binding(pat) = cx.tcx.hir().get(id); + if let Node::Pat(pat) = cx.tcx.hir().get(id); if let PatKind::Binding(ann, _, _, _) = pat.kind; if ann != BindingAnnotation::Mutable; then { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 5106c39b5c6fc..0a53ff6f47f12 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -183,7 +183,7 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> { let hir = cx.tcx.hir(); if_chain! { - if let Some(Node::Binding(pat)) = hir.find(hir_id); + if let Some(Node::Pat(pat)) = hir.find(hir_id); if matches!(pat.kind, PatKind::Binding(BindingAnnotation::Unannotated, ..)); let parent = hir.get_parent_node(hir_id); if let Some(Node::Local(local)) = hir.find(parent);