Auto merge of #122947 - matthiaskrgr:rollup-10j7orh, r=matthiaskrgr

Rollup of 11 pull requests

Successful merges:

 - #120577 (Stabilize slice_split_at_unchecked)
 - #122698 (Cancel `cargo update` job if there's no updates)
 - #122780 (Rename `hir::Local` into `hir::LetStmt`)
 - #122915 (Delay a bug if no RPITITs were found)
 - #122916 (docs(sync): normalize dot in fn summaries)
 - #122921 (Enable more mir-opt tests in debug builds)
 - #122922 (-Zprint-type-sizes: print the types of awaitees and unnamed coroutine locals.)
 - #122927 (Change an ICE regression test to use the original reproducer)
 - #122930 (add panic location to 'panicked while processing panic')
 - #122931 (Fix some typos in the pin.rs)
 - #122933 (tag_for_variant follow-ups)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-03-23 15:58:17 +00:00
commit 020bbe46bd
113 changed files with 567 additions and 280 deletions

View file

@ -42,7 +42,7 @@ jobs:
# Exit with error if open and S-waiting-on-bors # Exit with error if open and S-waiting-on-bors
if [[ "$STATE" == "OPEN" && "$WAITING_ON_BORS" == "true" ]]; then if [[ "$STATE" == "OPEN" && "$WAITING_ON_BORS" == "true" ]]; then
exit 1 gh run cancel ${{ github.run_id }}
fi fi
update: update:
@ -65,7 +65,10 @@ jobs:
- name: cargo update - name: cargo update
# Remove first line that always just says "Updating crates.io index" # Remove first line that always just says "Updating crates.io index"
run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log # If there are no changes, cancel the job here
run: |
cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
git status --porcelain | grep -q Cargo.lock || gh run cancel ${{ github.run_id }}
- name: upload Cargo.lock artifact for use in PR - name: upload Cargo.lock artifact for use in PR
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
@ -131,7 +134,7 @@ jobs:
# Exit with error if PR is closed # Exit with error if PR is closed
STATE=$(gh pr view cargo_update --repo $GITHUB_REPOSITORY --json state --jq '.state') STATE=$(gh pr view cargo_update --repo $GITHUB_REPOSITORY --json state --jq '.state')
if [[ "$STATE" != "OPEN" ]]; then if [[ "$STATE" != "OPEN" ]]; then
exit 1 gh run cancel ${{ github.run_id }}
fi fi
gh pr edit cargo_update --title "${PR_TITLE}" --body-file body.md --repo $GITHUB_REPOSITORY gh pr edit cargo_update --title "${PR_TITLE}" --body-file body.md --repo $GITHUB_REPOSITORY

View file

@ -81,7 +81,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(self.arena.alloc_from_iter(stmts), expr) (self.arena.alloc_from_iter(stmts), expr)
} }
fn lower_local(&mut self, l: &Local) -> &'hir hir::Local<'hir> { fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {
let ty = l let ty = l
.ty .ty
.as_ref() .as_ref()
@ -97,7 +97,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let span = self.lower_span(l.span); let span = self.lower_span(l.span);
let source = hir::LocalSource::Normal; let source = hir::LocalSource::Normal;
self.lower_attrs(hir_id, &l.attrs); self.lower_attrs(hir_id, &l.attrs);
self.arena.alloc(hir::Local { hir_id, ty, pat, init, els, span, source }) self.arena.alloc(hir::LetStmt { hir_id, ty, pat, init, els, span, source })
} }
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode { fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {

View file

@ -302,8 +302,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}); });
} }
fn visit_local(&mut self, l: &'hir Local<'hir>) { fn visit_local(&mut self, l: &'hir LetStmt<'hir>) {
self.insert(l.span, l.hir_id, Node::Local(l)); self.insert(l.span, l.hir_id, Node::LetStmt(l));
self.with_parent(l.hir_id, |this| { self.with_parent(l.hir_id, |this| {
intravisit::walk_local(this, l); intravisit::walk_local(this, l);
}) })

View file

@ -2341,7 +2341,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
debug_assert!(!a.is_empty()); debug_assert!(!a.is_empty());
self.attrs.insert(hir_id.local_id, a); self.attrs.insert(hir_id.local_id, a);
} }
let local = hir::Local { let local = hir::LetStmt {
hir_id, hir_id,
init, init,
pat, pat,

View file

@ -622,7 +622,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// FIXME: We make sure that this is a normal top-level binding, // FIXME: We make sure that this is a normal top-level binding,
// but we could suggest `todo!()` for all uninitalized bindings in the pattern pattern // but we could suggest `todo!()` for all uninitalized bindings in the pattern pattern
if let hir::StmtKind::Let(hir::Local { span, ty, init: None, pat, .. }) = if let hir::StmtKind::Let(hir::LetStmt { span, ty, init: None, pat, .. }) =
&ex.kind &ex.kind
&& let hir::PatKind::Binding(..) = pat.kind && let hir::PatKind::Binding(..) = pat.kind
&& span.contains(self.decl_span) && span.contains(self.decl_span)
@ -800,7 +800,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
for (_, node) in tcx.hir().parent_iter(expr.hir_id) { for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
let e = match node { let e = match node {
hir::Node::Expr(e) => e, hir::Node::Expr(e) => e,
hir::Node::Local(hir::Local { els: Some(els), .. }) => { hir::Node::LetStmt(hir::LetStmt { els: Some(els), .. }) => {
let mut finder = BreakFinder { found_breaks: vec![], found_continues: vec![] }; let mut finder = BreakFinder { found_breaks: vec![], found_continues: vec![] };
finder.visit_block(els); finder.visit_block(els);
if !finder.found_breaks.is_empty() { if !finder.found_breaks.is_empty() {
@ -2124,7 +2124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
hir::intravisit::walk_expr(self, e); hir::intravisit::walk_expr(self, e);
} }
fn visit_local(&mut self, local: &'hir hir::Local<'hir>) { fn visit_local(&mut self, local: &'hir hir::LetStmt<'hir>) {
if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } =
local.pat local.pat
&& let Some(init) = local.init && let Some(init) = local.init

View file

@ -558,7 +558,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
hir::intravisit::walk_stmt(self, stmt); hir::intravisit::walk_stmt(self, stmt);
let expr = match stmt.kind { let expr = match stmt.kind {
hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr, hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr,
hir::StmtKind::Let(hir::Local { init: Some(expr), .. }) => expr, hir::StmtKind::Let(hir::LetStmt { init: Some(expr), .. }) => expr,
_ => { _ => {
return; return;
} }
@ -737,7 +737,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&& let body = self.infcx.tcx.hir().body(body_id) && let body = self.infcx.tcx.hir().body(body_id)
&& let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value() && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value()
&& let node = self.infcx.tcx.hir_node(hir_id) && let node = self.infcx.tcx.hir_node(hir_id)
&& let hir::Node::Local(hir::Local { && let hir::Node::LetStmt(hir::LetStmt {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
.. ..
}) })
@ -1170,7 +1170,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}; };
if let Some(hir_id) = hir_id if let Some(hir_id) = hir_id
&& let hir::Node::Local(local) = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(local) = self.infcx.tcx.hir_node(hir_id)
{ {
let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap()); let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap());
if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait() if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()

View file

@ -3,7 +3,7 @@ use either::{Left, Right};
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo}; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::mir::{self, ConstAlloc, ConstValue};
use rustc_middle::query::{Key, TyCtxtAt}; use rustc_middle::query::TyCtxtAt;
use rustc_middle::traits::Reveal; use rustc_middle::traits::Reveal;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
@ -243,24 +243,6 @@ pub(crate) fn turn_into_const_value<'tcx>(
op_to_const(&ecx, &mplace.into(), /* for diagnostics */ false) op_to_const(&ecx, &mplace.into(), /* for diagnostics */ false)
} }
/// Computes the tag (if any) for a given type and variant.
#[instrument(skip(tcx), level = "debug")]
pub fn tag_for_variant_provider<'tcx>(
tcx: TyCtxt<'tcx>,
(ty, variant_index): (Ty<'tcx>, abi::VariantIdx),
) -> Option<ty::ScalarInt> {
assert!(ty.is_enum());
let ecx = InterpCx::new(
tcx,
ty.default_span(tcx),
ty::ParamEnv::reveal_all(),
crate::const_eval::DummyMachine,
);
ecx.tag_for_variant(ty, variant_index).unwrap().map(|(tag, _tag_field)| tag)
}
#[instrument(skip(tcx), level = "debug")] #[instrument(skip(tcx), level = "debug")]
pub fn eval_to_const_value_raw_provider<'tcx>( pub fn eval_to_const_value_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View file

@ -2,10 +2,11 @@
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::InterpErrorInfo; use rustc_middle::mir::interpret::InterpErrorInfo;
use rustc_middle::query::TyCtxtAt; use rustc_middle::query::{Key, TyCtxtAt};
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_target::abi::VariantIdx;
use crate::interpret::format_interp_error; use crate::interpret::{format_interp_error, InterpCx};
mod dummy_machine; mod dummy_machine;
mod error; mod error;
@ -77,3 +78,21 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
Some(mir::DestructuredConstant { variant, fields }) Some(mir::DestructuredConstant { variant, fields })
} }
/// Computes the tag (if any) for a given type and variant.
#[instrument(skip(tcx), level = "debug")]
pub fn tag_for_variant_provider<'tcx>(
tcx: TyCtxt<'tcx>,
(ty, variant_index): (Ty<'tcx>, VariantIdx),
) -> Option<ty::ScalarInt> {
assert!(ty.is_enum());
let ecx = InterpCx::new(
tcx,
ty.default_span(tcx),
ty::ParamEnv::reveal_all(),
crate::const_eval::DummyMachine,
);
ecx.tag_for_variant(ty, variant_index).unwrap().map(|(tag, _tag_field)| tag)
}

View file

@ -38,7 +38,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
None => { None => {
// No need to write the tag here, because an untagged variant is // No need to write the tag here, because an untagged variant is
// implicitly encoded. For `Niche`-optimized enums, it's by // implicitly encoded. For `Niche`-optimized enums, this works by
// simply by having a value that is outside the niche variants. // simply by having a value that is outside the niche variants.
// But what if the data stored here does not actually encode // But what if the data stored here does not actually encode
// this variant? That would be bad! So let's double-check... // this variant? That would be bad! So let's double-check...
@ -227,8 +227,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(ImmTy::from_scalar(discr_value, discr_layout)) Ok(ImmTy::from_scalar(discr_value, discr_layout))
} }
/// Computes the tag value and its field number (if any) of a given variant /// Computes how to write the tag of a given variant of enum `ty`:
/// of type `ty`. /// - `None` means that nothing needs to be done as the variant is encoded implicitly
/// - `Some((val, field_idx))` means that the given integer value needs to be stored at the
/// given field index.
pub(crate) fn tag_for_variant( pub(crate) fn tag_for_variant(
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,

View file

@ -1220,7 +1220,7 @@ pub struct Stmt<'hir> {
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum StmtKind<'hir> { pub enum StmtKind<'hir> {
/// A local (`let`) binding. /// A local (`let`) binding.
Let(&'hir Local<'hir>), Let(&'hir LetStmt<'hir>),
/// An item binding. /// An item binding.
Item(ItemId), Item(ItemId),
@ -1234,7 +1234,7 @@ pub enum StmtKind<'hir> {
/// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`). /// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`).
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Local<'hir> { pub struct LetStmt<'hir> {
pub pat: &'hir Pat<'hir>, pub pat: &'hir Pat<'hir>,
/// Type annotation, if any (otherwise the type will be inferred). /// Type annotation, if any (otherwise the type will be inferred).
pub ty: Option<&'hir Ty<'hir>>, pub ty: Option<&'hir Ty<'hir>>,
@ -1264,7 +1264,7 @@ pub struct Arm<'hir> {
pub body: &'hir Expr<'hir>, pub body: &'hir Expr<'hir>,
} }
/// Represents a `let <pat>[: <ty>] = <expr>` expression (not a [`Local`]), occurring in an `if-let` /// Represents a `let <pat>[: <ty>] = <expr>` expression (not a [`LetStmt`]), occurring in an `if-let`
/// or `let-else`, evaluating to a boolean. Typically the pattern is refutable. /// or `let-else`, evaluating to a boolean. Typically the pattern is refutable.
/// ///
/// In an `if let`, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of /// In an `if let`, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of
@ -1861,7 +1861,7 @@ pub enum ExprKind<'hir> {
DropTemps(&'hir Expr<'hir>), DropTemps(&'hir Expr<'hir>),
/// A `let $pat = $expr` expression. /// A `let $pat = $expr` expression.
/// ///
/// These are not `Local` and only occur as expressions. /// These are not [`LetStmt`] and only occur as expressions.
/// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`. /// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`.
Let(&'hir LetExpr<'hir>), Let(&'hir LetExpr<'hir>),
/// An `if` block, with an optional else block. /// An `if` block, with an optional else block.
@ -3529,7 +3529,7 @@ pub enum Node<'hir> {
PatField(&'hir PatField<'hir>), PatField(&'hir PatField<'hir>),
Arm(&'hir Arm<'hir>), Arm(&'hir Arm<'hir>),
Block(&'hir Block<'hir>), Block(&'hir Block<'hir>),
Local(&'hir Local<'hir>), LetStmt(&'hir LetStmt<'hir>),
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
/// with synthesized constructors. /// with synthesized constructors.
Ctor(&'hir VariantData<'hir>), Ctor(&'hir VariantData<'hir>),
@ -3585,7 +3585,7 @@ impl<'hir> Node<'hir> {
| Node::Ctor(..) | Node::Ctor(..)
| Node::Pat(..) | Node::Pat(..)
| Node::Arm(..) | Node::Arm(..)
| Node::Local(..) | Node::LetStmt(..)
| Node::Crate(..) | Node::Crate(..)
| Node::Ty(..) | Node::Ty(..)
| Node::TraitRef(..) | Node::TraitRef(..)
@ -3757,7 +3757,7 @@ impl<'hir> Node<'hir> {
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n; expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
expect_arm, &'hir Arm<'hir>, Node::Arm(n), n; expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;
expect_block, &'hir Block<'hir>, Node::Block(n), n; expect_block, &'hir Block<'hir>, Node::Block(n), n;
expect_local, &'hir Local<'hir>, Node::Local(n), n; expect_let_stmt, &'hir LetStmt<'hir>, Node::LetStmt(n), n;
expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n; expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n;
expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n; expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n;
expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n; expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
@ -3787,7 +3787,7 @@ mod size_asserts {
static_assert_size!(ImplItemKind<'_>, 40); static_assert_size!(ImplItemKind<'_>, 40);
static_assert_size!(Item<'_>, 88); static_assert_size!(Item<'_>, 88);
static_assert_size!(ItemKind<'_>, 56); static_assert_size!(ItemKind<'_>, 56);
static_assert_size!(Local<'_>, 64); static_assert_size!(LetStmt<'_>, 64);
static_assert_size!(Param<'_>, 32); static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72); static_assert_size!(Pat<'_>, 72);
static_assert_size!(Path<'_>, 40); static_assert_size!(Path<'_>, 40);

View file

@ -320,7 +320,7 @@ pub trait Visitor<'v>: Sized {
fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) -> Self::Result { fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) -> Self::Result {
walk_foreign_item(self, i) walk_foreign_item(self, i)
} }
fn visit_local(&mut self, l: &'v Local<'v>) -> Self::Result { fn visit_local(&mut self, l: &'v LetStmt<'v>) -> Self::Result {
walk_local(self, l) walk_local(self, l)
} }
fn visit_block(&mut self, b: &'v Block<'v>) -> Self::Result { fn visit_block(&mut self, b: &'v Block<'v>) -> Self::Result {
@ -606,7 +606,7 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
V::Result::output() V::Result::output()
} }
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) -> V::Result { pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v LetStmt<'v>) -> V::Result {
// Intentionally visiting the expr first - the initialization expr // Intentionally visiting the expr first - the initialization expr
// dominates the local's definition. // dominates the local's definition.
visit_opt!(visitor, visit_expr, local.init); visit_opt!(visitor, visit_expr, local.init);

View file

@ -639,10 +639,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
} }
} }
if !unnormalized_trait_sig.output().references_error() { if !unnormalized_trait_sig.output().references_error() && collector.types.is_empty() {
debug_assert!( tcx.dcx().delayed_bug(
!collector.types.is_empty(), "expect >0 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`",
"expect >0 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
); );
} }

View file

@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Arm, Block, Expr, Local, Pat, PatKind, Stmt}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt};
use rustc_index::Idx; use rustc_index::Idx;
use rustc_middle::middle::region::*; use rustc_middle::middle::region::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
@ -123,7 +123,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
for (i, statement) in blk.stmts.iter().enumerate() { for (i, statement) in blk.stmts.iter().enumerate() {
match statement.kind { match statement.kind {
hir::StmtKind::Let(hir::Local { els: Some(els), .. }) => { hir::StmtKind::Let(LetStmt { els: Some(els), .. }) => {
// Let-else has a special lexical structure for variables. // Let-else has a special lexical structure for variables.
// First we take a checkpoint of the current scope context here. // First we take a checkpoint of the current scope context here.
let mut prev_cx = visitor.cx; let mut prev_cx = visitor.cx;
@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
resolve_expr(self, ex); resolve_expr(self, ex);
} }
fn visit_local(&mut self, l: &'tcx Local<'tcx>) { fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) {
resolve_local(self, Some(l.pat), l.init) resolve_local(self, Some(l.pat), l.init)
} }
} }

View file

@ -113,7 +113,7 @@ impl<'a> State<'a> {
// `hir_map` to reconstruct their full structure for pretty // `hir_map` to reconstruct their full structure for pretty
// printing. // printing.
Node::Ctor(..) => panic!("cannot print isolated Ctor"), Node::Ctor(..) => panic!("cannot print isolated Ctor"),
Node::Local(a) => self.print_local_decl(a), Node::LetStmt(a) => self.print_local_decl(a),
Node::Crate(..) => panic!("cannot print Crate"), Node::Crate(..) => panic!("cannot print Crate"),
Node::WhereBoundPredicate(pred) => { Node::WhereBoundPredicate(pred) => {
self.print_formal_generic_params(pred.bound_generic_params); self.print_formal_generic_params(pred.bound_generic_params);
@ -1544,7 +1544,7 @@ impl<'a> State<'a> {
self.end() self.end()
} }
fn print_local_decl(&mut self, loc: &hir::Local<'_>) { fn print_local_decl(&mut self, loc: &hir::LetStmt<'_>) {
self.print_pat(loc.pat); self.print_pat(loc.pat);
if let Some(ty) = loc.ty { if let Some(ty) = loc.ty {
self.word_space(":"); self.word_space(":");

View file

@ -408,7 +408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
} }
if let hir::Node::Local(hir::Local { ty: Some(_), pat, .. }) = node { if let hir::Node::LetStmt(hir::LetStmt { ty: Some(_), pat, .. }) = node {
return Some((pat.span, "expected because of this assignment".to_string())); return Some((pat.span, "expected because of this assignment".to_string()));
} }
None None

View file

@ -299,8 +299,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false; return false;
}; };
let (init_ty_hir_id, init) = match self.tcx.parent_hir_node(pat.hir_id) { let (init_ty_hir_id, init) = match self.tcx.parent_hir_node(pat.hir_id) {
hir::Node::Local(hir::Local { ty: Some(ty), init, .. }) => (ty.hir_id, *init), hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init, .. }) => (ty.hir_id, *init),
hir::Node::Local(hir::Local { init: Some(init), .. }) => (init.hir_id, Some(*init)), hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => (init.hir_id, Some(*init)),
_ => return false, _ => return false,
}; };
let Some(init_ty) = self.node_ty_opt(init_ty_hir_id) else { let Some(init_ty) = self.node_ty_opt(init_ty_hir_id) else {
@ -678,7 +678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error: Option<TypeError<'tcx>>, error: Option<TypeError<'tcx>>,
) { ) {
match (self.tcx.parent_hir_node(expr.hir_id), error) { match (self.tcx.parent_hir_node(expr.hir_id), error) {
(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. }), _) (hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init: Some(init), .. }), _)
if init.hir_id == expr.hir_id => if init.hir_id == expr.hir_id =>
{ {
// Point at `let` assignment type. // Point at `let` assignment type.
@ -724,11 +724,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
primary_span = pat.span; primary_span = pat.span;
secondary_span = pat.span; secondary_span = pat.span;
match self.tcx.parent_hir_node(pat.hir_id) { match self.tcx.parent_hir_node(pat.hir_id) {
hir::Node::Local(hir::Local { ty: Some(ty), .. }) => { hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => {
primary_span = ty.span; primary_span = ty.span;
post_message = " type"; post_message = " type";
} }
hir::Node::Local(hir::Local { init: Some(init), .. }) => { hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => {
primary_span = init.span; primary_span = init.span;
post_message = " value"; post_message = " value";
} }

View file

@ -1451,7 +1451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
let Some(( let Some((
_, _,
hir::Node::Local(hir::Local { ty: Some(ty), .. }) hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. })
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }), | hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }),
)) = parent_node )) = parent_node
else { else {

View file

@ -371,7 +371,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) { fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
match stmt.kind { match stmt.kind {
hir::StmtKind::Let(hir::Local { pat, init: Some(expr), els, .. }) => { hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => {
self.walk_local(expr, pat, *els, |_| {}) self.walk_local(expr, pat, *els, |_| {})
} }

View file

@ -1601,7 +1601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
/// Type check a `let` statement. /// Type check a `let` statement.
pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) { pub fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) {
self.check_decl(local.into()); self.check_decl(local.into());
if local.pat.is_never_pattern() { if local.pat.is_never_pattern() {
self.diverges.set(Diverges::Always { self.diverges.set(Diverges::Always {
@ -1789,7 +1789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
[ [
hir::Stmt { hir::Stmt {
kind: kind:
hir::StmtKind::Let(hir::Local { hir::StmtKind::Let(hir::LetStmt {
source: source:
hir::LocalSource::AssignDesugar(_), hir::LocalSource::AssignDesugar(_),
.. ..

View file

@ -317,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
expr_id = parent_id; expr_id = parent_id;
} }
Node::Local(local) => { Node::LetStmt(local) => {
if let Some(mut ty) = local.ty { if let Some(mut ty) = local.ty {
while let Some(index) = tuple_indexes.pop() { while let Some(index) = tuple_indexes.pop() {
match ty.kind { match ty.kind {
@ -1348,7 +1348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// ++++++++++ // ++++++++++
// since the user probably just misunderstood how `let else` // since the user probably just misunderstood how `let else`
// and `&&` work together. // and `&&` work together.
if let Some((_, hir::Node::Local(local))) = cond_parent if let Some((_, hir::Node::LetStmt(local))) = cond_parent
&& let hir::PatKind::Path(qpath) | hir::PatKind::TupleStruct(qpath, _, _) = && let hir::PatKind::Path(qpath) | hir::PatKind::TupleStruct(qpath, _, _) =
&local.pat.kind &local.pat.kind
&& let hir::QPath::Resolved(None, path) = qpath && let hir::QPath::Resolved(None, path) = qpath
@ -1748,7 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match self.tcx.parent_hir_node(*hir_id) { match self.tcx.parent_hir_node(*hir_id) {
// foo.clone() // foo.clone()
hir::Node::Local(hir::Local { init: Some(init), .. }) => { hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => {
self.note_type_is_not_clone_inner_expr(init) self.note_type_is_not_clone_inner_expr(init)
} }
// When `expr` is more complex like a tuple // When `expr` is more complex like a tuple
@ -1757,7 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: hir::PatKind::Tuple(pats, ..), kind: hir::PatKind::Tuple(pats, ..),
.. ..
}) => { }) => {
let hir::Node::Local(hir::Local { init: Some(init), .. }) = let hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) =
self.tcx.parent_hir_node(*pat_hir_id) self.tcx.parent_hir_node(*pat_hir_id)
else { else {
return expr; return expr;
@ -1791,7 +1791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } = && let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } =
call_expr_path call_expr_path
&& let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding) && let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding)
&& let hir::Node::Local(hir::Local { init: Some(init), .. }) = && let hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) =
self.tcx.parent_hir_node(*hir_id) self.tcx.parent_hir_node(*hir_id)
&& let Expr { && let Expr {
kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }), kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }),
@ -3147,7 +3147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else { let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
return; return;
}; };
let hir::Node::Local(hir::Local { ty: None, init: Some(init), .. }) = let hir::Node::LetStmt(hir::LetStmt { ty: None, init: Some(init), .. }) =
self.tcx.parent_hir_node(pat.hir_id) self.tcx.parent_hir_node(pat.hir_id)
else { else {
return; return;

View file

@ -29,7 +29,7 @@ impl<'a> DeclOrigin<'a> {
} }
} }
/// A declaration is an abstraction of [hir::Local] and [hir::LetExpr]. /// A declaration is an abstraction of [hir::LetStmt] and [hir::LetExpr].
/// ///
/// It must have a hir_id, as this is how we connect gather_locals to the check functions. /// It must have a hir_id, as this is how we connect gather_locals to the check functions.
pub(super) struct Declaration<'a> { pub(super) struct Declaration<'a> {
@ -41,9 +41,9 @@ pub(super) struct Declaration<'a> {
pub origin: DeclOrigin<'a>, pub origin: DeclOrigin<'a>,
} }
impl<'a> From<&'a hir::Local<'a>> for Declaration<'a> { impl<'a> From<&'a hir::LetStmt<'a>> for Declaration<'a> {
fn from(local: &'a hir::Local<'a>) -> Self { fn from(local: &'a hir::LetStmt<'a>) -> Self {
let hir::Local { hir_id, pat, ty, span, init, els, source: _ } = *local; let hir::LetStmt { hir_id, pat, ty, span, init, els, source: _ } = *local;
Declaration { hir_id, pat, ty, span, init, origin: DeclOrigin::LocalDecl { els } } Declaration { hir_id, pat, ty, span, init, origin: DeclOrigin::LocalDecl { els } }
} }
} }
@ -120,7 +120,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
// Add explicitly-declared locals. // Add explicitly-declared locals.
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
self.declare(local.into()); self.declare(local.into());
intravisit::walk_local(self, local) intravisit::walk_local(self, local)
} }

View file

@ -2163,7 +2163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match (filename, parent_node) { match (filename, parent_node) {
( (
FileName::Real(_), FileName::Real(_),
Node::Local(hir::Local { Node::LetStmt(hir::LetStmt {
source: hir::LocalSource::Normal, source: hir::LocalSource::Normal,
ty, ty,
.. ..
@ -2218,7 +2218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
impl<'v> Visitor<'v> for LetVisitor { impl<'v> Visitor<'v> for LetVisitor {
type Result = ControlFlow<Option<&'v hir::Expr<'v>>>; type Result = ControlFlow<Option<&'v hir::Expr<'v>>>;
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result { fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result {
if let hir::StmtKind::Let(&hir::Local { pat, init, .. }) = ex.kind if let hir::StmtKind::Let(&hir::LetStmt { pat, init, .. }) = ex.kind
&& let Binding(_, _, ident, ..) = pat.kind && let Binding(_, _, ident, ..) = pat.kind
&& ident.name == self.ident_name && ident.name == self.ident_name
{ {

View file

@ -744,7 +744,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ident_kind = match binding_parent { let ident_kind = match binding_parent {
hir::Node::Param(_) => "parameter", hir::Node::Param(_) => "parameter",
hir::Node::Local(_) => "variable", hir::Node::LetStmt(_) => "variable",
hir::Node::Arm(_) => "binding", hir::Node::Arm(_) => "binding",
// Provide diagnostics only if the parent pattern is struct-like, // Provide diagnostics only if the parent pattern is struct-like,

View file

@ -217,7 +217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bug!(); bug!();
}; };
for stmt in block.stmts { for stmt in block.stmts {
let hir::StmtKind::Let(hir::Local { let hir::StmtKind::Let(hir::LetStmt {
init: Some(init), init: Some(init),
source: hir::LocalSource::AsyncFn, source: hir::LocalSource::AsyncFn,
pat, pat,

View file

@ -351,7 +351,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
intravisit::walk_pat(self, p); intravisit::walk_pat(self, p);
} }
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, l: &'tcx hir::LetStmt<'tcx>) {
intravisit::walk_local(self, l); intravisit::walk_local(self, l);
let var_ty = self.fcx.local_ty(l.span, l.hir_id); let var_ty = self.fcx.local_ty(l.span, l.hir_id);
let var_ty = self.resolve(var_ty, &l.span); let var_ty = self.resolve(var_ty, &l.span);

View file

@ -2140,7 +2140,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// the same span as the error and the type is specified. // the same span as the error and the type is specified.
if let hir::Stmt { if let hir::Stmt {
kind: kind:
hir::StmtKind::Let(hir::Local { hir::StmtKind::Let(hir::LetStmt {
init: Some(hir::Expr { span: init_span, .. }), init: Some(hir::Expr { span: init_span, .. }),
ty: Some(array_ty), ty: Some(array_ty),
.. ..

View file

@ -11,7 +11,7 @@ use rustc_hir::def::Res;
use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::infer::unify_key::{ use rustc_middle::infer::unify_key::{
ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue, ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue,
@ -1122,7 +1122,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
self.tecx.tcx.hir() self.tecx.tcx.hir()
} }
fn visit_local(&mut self, local: &'tcx Local<'tcx>) { fn visit_local(&mut self, local: &'tcx LetStmt<'tcx>) {
intravisit::walk_local(self, local); intravisit::walk_local(self, local);
if let Some(ty) = self.opt_node_type(local.hir_id) { if let Some(ty) = self.opt_node_type(local.hir_id) {

View file

@ -2,7 +2,7 @@ use crate::infer::error_reporting::hir::Path;
use core::ops::ControlFlow; use core::ops::ControlFlow;
use hir::def::CtorKind; use hir::def::CtorKind;
use hir::intravisit::{walk_expr, walk_stmt, Visitor}; use hir::intravisit::{walk_expr, walk_stmt, Visitor};
use hir::{Local, QPath}; use hir::{LetStmt, QPath};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diag}; use rustc_errors::{Applicability, Diag};
use rustc_hir as hir; use rustc_hir as hir;
@ -321,7 +321,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& let Some(expr) = block.expr && let Some(expr) = block.expr
&& let hir::ExprKind::Path(QPath::Resolved(_, Path { res, .. })) = expr.kind && let hir::ExprKind::Path(QPath::Resolved(_, Path { res, .. })) = expr.kind
&& let Res::Local(local) = res && let Res::Local(local) = res
&& let Node::Local(Local { init: Some(init), .. }) = self.tcx.parent_hir_node(*local) && let Node::LetStmt(LetStmt { init: Some(init), .. }) =
self.tcx.parent_hir_node(*local)
{ {
fn collect_blocks<'hir>(expr: &hir::Expr<'hir>, blocks: &mut Vec<&hir::Block<'hir>>) { fn collect_blocks<'hir>(expr: &hir::Expr<'hir>, blocks: &mut Vec<&hir::Block<'hir>>) {
match expr.kind { match expr.kind {
@ -585,7 +586,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result { fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result {
if let hir::StmtKind::Let(hir::Local { if let hir::StmtKind::Let(LetStmt {
span, span,
pat: hir::Pat { .. }, pat: hir::Pat { .. },
ty: None, ty: None,

View file

@ -937,7 +937,7 @@ impl<'tcx> LateContext<'tcx> {
} }
&& let Some(init) = match parent_node { && let Some(init) = match parent_node {
hir::Node::Expr(expr) => Some(expr), hir::Node::Expr(expr) => Some(expr),
hir::Node::Local(hir::Local { init, .. }) => *init, hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
_ => None, _ => None,
} }
{ {
@ -982,7 +982,7 @@ impl<'tcx> LateContext<'tcx> {
} }
&& let Some(init) = match parent_node { && let Some(init) = match parent_node {
hir::Node::Expr(expr) => Some(expr), hir::Node::Expr(expr) => Some(expr),
hir::Node::Local(hir::Local { init, .. }) => *init, hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
hir::Node::Item(item) => match item.kind { hir::Node::Item(item) => match item.kind {
hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => { hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => {
Some(self.tcx.hir().body(body_id).value) Some(self.tcx.hir().body(body_id).value)

View file

@ -238,7 +238,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
} }
} }
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, l: &'tcx hir::LetStmt<'tcx>) {
self.with_lint_attrs(l.hir_id, |cx| { self.with_lint_attrs(l.hir_id, |cx| {
lint_callback!(cx, check_local, l); lint_callback!(cx, check_local, l);
hir_visit::walk_local(cx, l); hir_visit::walk_local(cx, l);

View file

@ -105,7 +105,7 @@ const SYNC_GUARD_SYMBOLS: [Symbol; 3] = [
impl<'tcx> LateLintPass<'tcx> for LetUnderscore { impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) { fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::LetStmt<'_>) {
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) { if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
return; return;
} }

View file

@ -354,7 +354,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
intravisit::walk_variant(self, v); intravisit::walk_variant(self, v);
} }
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, l: &'tcx hir::LetStmt<'tcx>) {
self.add_id(l.hir_id); self.add_id(l.hir_id);
intravisit::walk_local(self, l); intravisit::walk_local(self, l);
} }
@ -428,7 +428,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'
intravisit::walk_variant(self, v); intravisit::walk_variant(self, v);
} }
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, l: &'tcx hir::LetStmt<'tcx>) {
self.add_id(l.hir_id); self.add_id(l.hir_id);
intravisit::walk_local(self, l); intravisit::walk_local(self, l);
} }

View file

@ -15,7 +15,7 @@ macro_rules! late_lint_methods {
fn check_foreign_item(a: &'tcx rustc_hir::ForeignItem<'tcx>); fn check_foreign_item(a: &'tcx rustc_hir::ForeignItem<'tcx>);
fn check_item(a: &'tcx rustc_hir::Item<'tcx>); fn check_item(a: &'tcx rustc_hir::Item<'tcx>);
fn check_item_post(a: &'tcx rustc_hir::Item<'tcx>); fn check_item_post(a: &'tcx rustc_hir::Item<'tcx>);
fn check_local(a: &'tcx rustc_hir::Local<'tcx>); fn check_local(a: &'tcx rustc_hir::LetStmt<'tcx>);
fn check_block(a: &'tcx rustc_hir::Block<'tcx>); fn check_block(a: &'tcx rustc_hir::Block<'tcx>);
fn check_block_post(a: &'tcx rustc_hir::Block<'tcx>); fn check_block_post(a: &'tcx rustc_hir::Block<'tcx>);
fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>); fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);

View file

@ -46,7 +46,7 @@ declare_lint! {
declare_lint_pass!(UnitBindings => [UNIT_BINDINGS]); declare_lint_pass!(UnitBindings => [UNIT_BINDINGS]);
impl<'tcx> LateLintPass<'tcx> for UnitBindings { impl<'tcx> LateLintPass<'tcx> for UnitBindings {
fn check_local(&mut self, cx: &crate::LateContext<'tcx>, local: &'tcx hir::Local<'tcx>) { fn check_local(&mut self, cx: &crate::LateContext<'tcx>, local: &'tcx hir::LetStmt<'tcx>) {
// Suppress warning if user: // Suppress warning if user:
// - explicitly ascribes a type to the pattern // - explicitly ascribes a type to the pattern
// - explicitly wrote `let pat = ();` // - explicitly wrote `let pat = ();`

View file

@ -567,7 +567,7 @@ impl<'hir> Map<'hir> {
} }
// Ignore `return`s on the first iteration // Ignore `return`s on the first iteration
Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. }) Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. })
| Node::Local(_) => { | Node::LetStmt(_) => {
return None; return None;
} }
_ => {} _ => {}
@ -906,7 +906,7 @@ impl<'hir> Map<'hir> {
Node::Lifetime(lifetime) => lifetime.ident.span, Node::Lifetime(lifetime) => lifetime.ident.span,
Node::GenericParam(param) => param.span, Node::GenericParam(param) => param.span,
Node::Infer(i) => i.span, Node::Infer(i) => i.span,
Node::Local(local) => local.span, Node::LetStmt(local) => local.span,
Node::Crate(item) => item.spans.inner_span, Node::Crate(item) => item.spans.inner_span,
Node::WhereBoundPredicate(pred) => pred.span, Node::WhereBoundPredicate(pred) => pred.span,
Node::ArrayLenInfer(inf) => inf.span, Node::ArrayLenInfer(inf) => inf.span,
@ -1163,7 +1163,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
Node::Arm(_) => node_str("arm"), Node::Arm(_) => node_str("arm"),
Node::Block(_) => node_str("block"), Node::Block(_) => node_str("block"),
Node::Infer(_) => node_str("infer"), Node::Infer(_) => node_str("infer"),
Node::Local(_) => node_str("local"), Node::LetStmt(_) => node_str("local"),
Node::Ctor(ctor) => format!( Node::Ctor(ctor) => format!(
"{id} (ctor {})", "{id} (ctor {})",
ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)), ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)),

View file

@ -264,7 +264,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_foreign_item(self, i) hir_visit::walk_foreign_item(self, i)
} }
fn visit_local(&mut self, l: &'v hir::Local<'v>) { fn visit_local(&mut self, l: &'v hir::LetStmt<'v>) {
self.record("Local", Id::Node(l.hir_id), l); self.record("Local", Id::Node(l.hir_id), l);
hir_visit::walk_local(self, l) hir_visit::walk_local(self, l)
} }

View file

@ -342,7 +342,7 @@ impl<'tcx> IrMaps<'tcx> {
} }
impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
self.add_from_pat(local.pat); self.add_from_pat(local.pat);
if local.els.is_some() { if local.els.is_some() {
self.add_live_node_for_node(local.hir_id, ExprNode(local.span, local.hir_id)); self.add_live_node_for_node(local.hir_id, ExprNode(local.span, local.hir_id));
@ -1350,7 +1350,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// Checking for error conditions // Checking for error conditions
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
self.check_unused_vars_in_pat(local.pat, None, None, |spans, hir_id, ln, var| { self.check_unused_vars_in_pat(local.pat, None, None, |spans, hir_id, ln, var| {
if local.init.is_some() { if local.init.is_some() {
self.warn_about_dead_assign(spans, hir_id, ln, var); self.warn_about_dead_assign(spans, hir_id, ln, var);

View file

@ -1209,7 +1209,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
intravisit::walk_pat(self, pattern); intravisit::walk_pat(self, pattern);
} }
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) { fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
if let Some(init) = local.init { if let Some(init) = local.init {
if self.check_expr_pat_type(init.hir_id, init.span) { if self.check_expr_pat_type(init.hir_id, init.span) {
// Do not report duplicate errors for `let x = y`. // Do not report duplicate errors for `let x = y`.

View file

@ -44,6 +44,10 @@ pub struct FieldInfo {
pub offset: u64, pub offset: u64,
pub size: u64, pub size: u64,
pub align: u64, pub align: u64,
/// Name of the type of this field.
/// Present only if the creator thought that this would be important for identifying the field,
/// typically because the field name is uninformative.
pub type_name: Option<Symbol>,
} }
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@ -192,7 +196,7 @@ impl CodeStats {
fields.sort_by_key(|f| (f.offset, f.size)); fields.sort_by_key(|f| (f.offset, f.size));
for field in fields { for field in fields {
let FieldInfo { kind, ref name, offset, size, align } = field; let FieldInfo { kind, ref name, offset, size, align, type_name } = field;
if offset > min_offset { if offset > min_offset {
let pad = offset - min_offset; let pad = offset - min_offset;
@ -201,21 +205,27 @@ impl CodeStats {
if offset < min_offset { if offset < min_offset {
// If this happens it's probably a union. // If this happens it's probably a union.
println!( print!(
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \ "print-type-size {indent}{kind} `.{name}`: {size} bytes, \
offset: {offset} bytes, \ offset: {offset} bytes, \
alignment: {align} bytes" alignment: {align} bytes"
); );
} else if info.packed || offset == min_offset { } else if info.packed || offset == min_offset {
println!("print-type-size {indent}{kind} `.{name}`: {size} bytes"); print!("print-type-size {indent}{kind} `.{name}`: {size} bytes");
} else { } else {
// Include field alignment in output only if it caused padding injection // Include field alignment in output only if it caused padding injection
println!( print!(
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \ "print-type-size {indent}{kind} `.{name}`: {size} bytes, \
alignment: {align} bytes" alignment: {align} bytes"
); );
} }
if let Some(type_name) = type_name {
println!(", type: {type_name}");
} else {
println!();
}
min_offset = offset + size; min_offset = offset + size;
} }
} }

View file

@ -768,7 +768,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
// Different to previous arm because one is `&hir::Local` and the other // Different to previous arm because one is `&hir::Local` and the other
// is `P<hir::Local>`. // is `P<hir::Local>`.
hir::Node::Local(local) => get_name(err, &local.pat.kind), hir::Node::LetStmt(local) => get_name(err, &local.pat.kind),
_ => None, _ => None,
} }
} }
@ -930,7 +930,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else { let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
return; return;
}; };
let hir::Node::Local(hir::Local { ty: None, init: Some(init), .. }) = let hir::Node::LetStmt(hir::LetStmt { ty: None, init: Some(init), .. }) =
self.tcx.parent_hir_node(pat.hir_id) self.tcx.parent_hir_node(pat.hir_id)
else { else {
return; return;
@ -1562,7 +1562,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let Res::Local(hir_id) = path.res && let Res::Local(hir_id) = path.res
&& let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id) && let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id)
&& let hir::Node::Local(local) = self.tcx.parent_hir_node(binding.hir_id) && let hir::Node::LetStmt(local) = self.tcx.parent_hir_node(binding.hir_id)
&& let None = local.ty && let None = local.ty
&& let Some(binding_expr) = local.init && let Some(binding_expr) = local.init
{ {
@ -2966,7 +2966,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.downgrade_to_delayed_bug(); err.downgrade_to_delayed_bug();
} }
match tcx.parent_hir_node(hir_id) { match tcx.parent_hir_node(hir_id) {
Node::Local(hir::Local { ty: Some(ty), .. }) => { Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => {
err.span_suggestion_verbose( err.span_suggestion_verbose(
ty.span.shrink_to_lo(), ty.span.shrink_to_lo(),
"consider borrowing here", "consider borrowing here",
@ -2975,7 +2975,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
); );
err.note("all local variables must have a statically known size"); err.note("all local variables must have a statically known size");
} }
Node::Local(hir::Local { Node::LetStmt(hir::LetStmt {
init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }), init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
.. ..
}) => { }) => {
@ -3867,7 +3867,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: Res::Local(hir_id), .. } = path && let hir::Path { res: Res::Local(hir_id), .. } = path
&& let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id) && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
&& let hir::Node::Local(local) = self.tcx.parent_hir_node(binding.hir_id) && let hir::Node::LetStmt(local) = self.tcx.parent_hir_node(binding.hir_id)
&& let Some(binding_expr) = local.init && let Some(binding_expr) = local.init
{ {
// If the expression we're calling on is a binding, we want to point at the // If the expression we're calling on is a binding, we want to point at the
@ -4128,7 +4128,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
{ {
let parent = self.tcx.parent_hir_node(binding.hir_id); let parent = self.tcx.parent_hir_node(binding.hir_id);
// We've reached the root of the method call chain... // We've reached the root of the method call chain...
if let hir::Node::Local(local) = parent if let hir::Node::LetStmt(local) = parent
&& let Some(binding_expr) = local.init && let Some(binding_expr) = local.init
{ {
// ...and it is a binding. Get the binding creation and continue the chain. // ...and it is a binding. Get the binding creation and continue the chain.

View file

@ -1272,7 +1272,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
{ {
let parent = self.tcx.parent_hir_node(binding.hir_id); let parent = self.tcx.parent_hir_node(binding.hir_id);
// We've reached the root of the method call chain... // We've reached the root of the method call chain...
if let hir::Node::Local(local) = parent if let hir::Node::LetStmt(local) = parent
&& let Some(binding_expr) = local.init && let Some(binding_expr) = local.init
{ {
// ...and it is a binding. Get the binding creation and continue the chain. // ...and it is a binding. Get the binding creation and continue the chain.

View file

@ -10,6 +10,7 @@ use rustc_middle::ty::layout::{
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use rustc_span::sym;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_target::abi::*; use rustc_target::abi::*;
@ -1007,6 +1008,7 @@ fn variant_info_for_adt<'tcx>(
offset: offset.bytes(), offset: offset.bytes(),
size: field_layout.size.bytes(), size: field_layout.size.bytes(),
align: field_layout.align.abi.bytes(), align: field_layout.align.abi.bytes(),
type_name: None,
} }
}) })
.collect(); .collect();
@ -1090,6 +1092,7 @@ fn variant_info_for_coroutine<'tcx>(
offset: offset.bytes(), offset: offset.bytes(),
size: field_layout.size.bytes(), size: field_layout.size.bytes(),
align: field_layout.align.abi.bytes(), align: field_layout.align.abi.bytes(),
type_name: None,
} }
}) })
.collect(); .collect();
@ -1104,19 +1107,24 @@ fn variant_info_for_coroutine<'tcx>(
.iter() .iter()
.enumerate() .enumerate()
.map(|(field_idx, local)| { .map(|(field_idx, local)| {
let field_name = coroutine.field_names[*local];
let field_layout = variant_layout.field(cx, field_idx); let field_layout = variant_layout.field(cx, field_idx);
let offset = variant_layout.fields.offset(field_idx); let offset = variant_layout.fields.offset(field_idx);
// The struct is as large as the last field's end // The struct is as large as the last field's end
variant_size = variant_size.max(offset + field_layout.size); variant_size = variant_size.max(offset + field_layout.size);
FieldInfo { FieldInfo {
kind: FieldKind::CoroutineLocal, kind: FieldKind::CoroutineLocal,
name: coroutine.field_names[*local].unwrap_or(Symbol::intern(&format!( name: field_name.unwrap_or(Symbol::intern(&format!(
".coroutine_field{}", ".coroutine_field{}",
local.as_usize() local.as_usize()
))), ))),
offset: offset.bytes(), offset: offset.bytes(),
size: field_layout.size.bytes(), size: field_layout.size.bytes(),
align: field_layout.align.abi.bytes(), align: field_layout.align.abi.bytes(),
// Include the type name if there is no field name, or if the name is the
// __awaitee placeholder symbol which means a child future being `.await`ed.
type_name: (field_name.is_none() || field_name == Some(sym::__awaitee))
.then(|| Symbol::intern(&field_layout.ty.to_string())),
} }
}) })
.chain(upvar_fields.iter().copied()) .chain(upvar_fields.iter().copied())

View file

@ -190,7 +190,6 @@
#![feature(ptr_metadata)] #![feature(ptr_metadata)]
#![feature(set_ptr_value)] #![feature(set_ptr_value)]
#![feature(slice_ptr_get)] #![feature(slice_ptr_get)]
#![feature(slice_split_at_unchecked)]
#![feature(split_at_checked)] #![feature(split_at_checked)]
#![feature(str_internals)] #![feature(str_internals)]
#![feature(str_split_inclusive_remainder)] #![feature(str_split_inclusive_remainder)]

View file

@ -161,11 +161,12 @@ impl fmt::Display for PanicInfo<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("panicked at ")?; formatter.write_str("panicked at ")?;
self.location.fmt(formatter)?; self.location.fmt(formatter)?;
formatter.write_str(":")?;
if let Some(message) = self.message { if let Some(message) = self.message {
formatter.write_str(":\n")?; formatter.write_str("\n")?;
formatter.write_fmt(*message)?; formatter.write_fmt(*message)?;
} else if let Some(payload) = self.payload.downcast_ref::<&'static str>() { } else if let Some(payload) = self.payload.downcast_ref::<&'static str>() {
formatter.write_str(":\n")?; formatter.write_str("\n")?;
formatter.write_str(payload)?; formatter.write_str(payload)?;
} }
// NOTE: we cannot use downcast_ref::<String>() here // NOTE: we cannot use downcast_ref::<String>() here

View file

@ -144,7 +144,7 @@
//! * e.g. [`drop`]ping the [`Future`] [^pin-drop-future] //! * e.g. [`drop`]ping the [`Future`] [^pin-drop-future]
//! //!
//! There are two possible ways to ensure the invariants required for 2. and 3. above (which //! There are two possible ways to ensure the invariants required for 2. and 3. above (which
//! apply to any address-sensitive type, not just self-referrential types) do not get broken. //! apply to any address-sensitive type, not just self-referential types) do not get broken.
//! //!
//! 1. Have the value detect when it is moved and update all the pointers that point to itself. //! 1. Have the value detect when it is moved and update all the pointers that point to itself.
//! 2. Guarantee that the address of the value does not change (and that memory is not re-used //! 2. Guarantee that the address of the value does not change (and that memory is not re-used
@ -170,7 +170,7 @@
//! become viral throughout all code that interacts with the object. //! become viral throughout all code that interacts with the object.
//! //!
//! The second option is a viable solution to the problem for some use cases, in particular //! The second option is a viable solution to the problem for some use cases, in particular
//! for self-referrential types. Under this model, any type that has an address sensitive state //! for self-referential types. Under this model, any type that has an address sensitive state
//! would ultimately store its data in something like a [`Box<T>`], carefully manage internal //! would ultimately store its data in something like a [`Box<T>`], carefully manage internal
//! access to that data to ensure no *moves* or other invalidation occurs, and finally //! access to that data to ensure no *moves* or other invalidation occurs, and finally
//! provide a safe interface on top. //! provide a safe interface on top.
@ -186,8 +186,8 @@
//! //!
//! Although there were other reason as well, this issue of expensive composition is the key thing //! Although there were other reason as well, this issue of expensive composition is the key thing
//! that drove Rust towards adopting a different model. It is particularly a problem //! that drove Rust towards adopting a different model. It is particularly a problem
//! when one considers, for exapmle, the implications of composing together the [`Future`]s which //! when one considers, for example, the implications of composing together the [`Future`]s which
//! will eventaully make up an asynchronous task (including address-sensitive `async fn` state //! will eventually make up an asynchronous task (including address-sensitive `async fn` state
//! machines). It is plausible that there could be many layers of [`Future`]s composed together, //! machines). It is plausible that there could be many layers of [`Future`]s composed together,
//! including multiple layers of `async fn`s handling different parts of a task. It was deemed //! including multiple layers of `async fn`s handling different parts of a task. It was deemed
//! unacceptable to force indirection and allocation for each layer of composition in this case. //! unacceptable to force indirection and allocation for each layer of composition in this case.
@ -359,7 +359,7 @@
//! Builtin types that are [`Unpin`] include all of the primitive types, like [`bool`], [`i32`], //! Builtin types that are [`Unpin`] include all of the primitive types, like [`bool`], [`i32`],
//! and [`f32`], references (<code>[&]T</code> and <code>[&mut] T</code>), etc., as well as many //! and [`f32`], references (<code>[&]T</code> and <code>[&mut] T</code>), etc., as well as many
//! core and standard library types like [`Box<T>`], [`String`], and more. //! core and standard library types like [`Box<T>`], [`String`], and more.
//! These types are marked [`Unpin`] because they do not have an ddress-sensitive state like the //! These types are marked [`Unpin`] because they do not have an address-sensitive state like the
//! ones we discussed above. If they did have such a state, those parts of their interface would be //! ones we discussed above. If they did have such a state, those parts of their interface would be
//! unsound without being expressed through pinning, and they would then need to not //! unsound without being expressed through pinning, and they would then need to not
//! implement [`Unpin`]. //! implement [`Unpin`].
@ -953,7 +953,7 @@ use crate::{
/// discussed below. /// discussed below.
/// ///
/// We call such a [`Pin`]-wrapped pointer a **pinning pointer** (or pinning ref, or pinning /// We call such a [`Pin`]-wrapped pointer a **pinning pointer** (or pinning ref, or pinning
/// [`Box`], etc.) because its existince is the thing that is pinning the underlying pointee in /// [`Box`], etc.) because its existence is the thing that is pinning the underlying pointee in
/// place: it is the metaphorical "pin" securing the data in place on the pinboard (in memory). /// place: it is the metaphorical "pin" securing the data in place on the pinboard (in memory).
/// ///
/// It is important to stress that the thing in the [`Pin`] is not the value which we want to pin /// It is important to stress that the thing in the [`Pin`] is not the value which we want to pin
@ -962,7 +962,7 @@ use crate::{
/// ///
/// The most common set of types which require pinning related guarantees for soundness are the /// The most common set of types which require pinning related guarantees for soundness are the
/// compiler-generated state machines that implement [`Future`] for the return value of /// compiler-generated state machines that implement [`Future`] for the return value of
/// `async fn`s. These compiler-generated [`Future`]s may contain self-referrential pointers, one /// `async fn`s. These compiler-generated [`Future`]s may contain self-referential pointers, one
/// of the most common use cases for [`Pin`]. More details on this point are provided in the /// of the most common use cases for [`Pin`]. More details on this point are provided in the
/// [`pin` module] docs, but suffice it to say they require the guarantees provided by pinning to /// [`pin` module] docs, but suffice it to say they require the guarantees provided by pinning to
/// be implemented soundly. /// be implemented soundly.

View file

@ -1944,8 +1944,6 @@ impl<T> [T] {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(slice_split_at_unchecked)]
///
/// let v = [1, 2, 3, 4, 5, 6]; /// let v = [1, 2, 3, 4, 5, 6];
/// ///
/// unsafe { /// unsafe {
@ -1966,7 +1964,7 @@ impl<T> [T] {
/// assert_eq!(right, []); /// assert_eq!(right, []);
/// } /// }
/// ``` /// ```
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] #[stable(feature = "slice_split_at_unchecked", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")]
#[inline] #[inline]
#[must_use] #[must_use]
@ -2008,8 +2006,6 @@ impl<T> [T] {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(slice_split_at_unchecked)]
///
/// let mut v = [1, 0, 3, 0, 5, 6]; /// let mut v = [1, 0, 3, 0, 5, 6];
/// // scoped to restrict the lifetime of the borrows /// // scoped to restrict the lifetime of the borrows
/// unsafe { /// unsafe {
@ -2021,7 +2017,7 @@ impl<T> [T] {
/// } /// }
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]); /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
/// ``` /// ```
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] #[stable(feature = "slice_split_at_unchecked", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")] #[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")]
#[inline] #[inline]
#[must_use] #[must_use]

View file

@ -746,7 +746,13 @@ fn rust_panic_with_hook(
panic_count::MustAbort::PanicInHook => { panic_count::MustAbort::PanicInHook => {
// Don't try to print the message in this case // Don't try to print the message in this case
// - perhaps that is causing the recursive panics. // - perhaps that is causing the recursive panics.
rtprintpanic!("thread panicked while processing panic. aborting.\n"); let panicinfo = PanicInfo::internal_constructor(
None, // no message
location, // but we want to show the location!
can_unwind,
force_no_backtrace,
);
rtprintpanic!("{panicinfo}\nthread panicked while processing panic. aborting.\n");
} }
panic_count::MustAbort::AlwaysAbort => { panic_count::MustAbort::AlwaysAbort => {
// Unfortunately, this does not print a backtrace, because creating // Unfortunately, this does not print a backtrace, because creating

View file

@ -396,7 +396,7 @@ impl<T: ?Sized> Mutex<T> {
self.poison.get() self.poison.get()
} }
/// Clear the poisoned state from a mutex /// Clear the poisoned state from a mutex.
/// ///
/// If the mutex is poisoned, it will remain poisoned until this function is called. This /// If the mutex is poisoned, it will remain poisoned until this function is called. This
/// allows recovering from a poisoned state and marking that it has recovered. For example, if /// allows recovering from a poisoned state and marking that it has recovered. For example, if

View file

@ -439,7 +439,7 @@ impl<T: ?Sized> RwLock<T> {
self.poison.get() self.poison.get()
} }
/// Clear the poisoned state from a lock /// Clear the poisoned state from a lock.
/// ///
/// If the lock is poisoned, it will remain poisoned until this function is called. This allows /// If the lock is poisoned, it will remain poisoned until this function is called. This allows
/// recovering from a poisoned state and marking that it has recovered. For example, if the /// recovering from a poisoned state and marking that it has recovered. For example, if the

View file

@ -163,7 +163,7 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC
// TODO: This check currently bails if the local variable has no initializer. // TODO: This check currently bails if the local variable has no initializer.
// That is overly conservative - the lint should fire even if there was no initializer, // That is overly conservative - the lint should fire even if there was no initializer,
// but the variable has been initialized before `lhs` was evaluated. // but the variable has been initialized before `lhs` was evaluated.
if let Some(Node::Local(local)) = cx.tcx.hir().parent_id_iter(local).next().map(|p| cx.tcx.hir_node(p)) if let Some(Node::LetStmt(local)) = cx.tcx.hir().parent_id_iter(local).next().map(|p| cx.tcx.hir_node(p))
&& local.init.is_none() && local.init.is_none()
{ {
return false; return false;

View file

@ -6,7 +6,7 @@ use clippy_utils::{is_default_equivalent, path_def_id};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, Ty, TyKind}; use rustc_hir::{Block, Expr, ExprKind, LetStmt, Node, QPath, Ty, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::print::with_forced_trimmed_paths;
@ -139,7 +139,7 @@ impl<'tcx> Visitor<'tcx> for InferVisitor {
fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
match cx.tcx.parent_hir_node(expr.hir_id) { match cx.tcx.parent_hir_node(expr.hir_id) {
Node::Local(Local { ty: Some(ty), .. }) => { Node::LetStmt(LetStmt { ty: Some(ty), .. }) => {
let mut v = InferVisitor::default(); let mut v = InferVisitor::default();
v.visit_ty(ty); v.visit_ty(ty);
!v.0 !v.0

View file

@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(
&& let ty::RawPtr(_, to_mutbl) = cast_to.kind() && let ty::RawPtr(_, to_mutbl) = cast_to.kind()
&& let Some(use_cx) = expr_use_ctxt(cx, expr) && let Some(use_cx) = expr_use_ctxt(cx, expr)
// TODO: only block the lint if `cast_expr` is a temporary // TODO: only block the lint if `cast_expr` is a temporary
&& !matches!(use_cx.node, ExprUseNode::Local(_) | ExprUseNode::ConstStatic(_)) && !matches!(use_cx.node, ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_))
{ {
let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" }; let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
let fn_name = match to_mutbl { let fn_name = match to_mutbl {

View file

@ -66,7 +66,7 @@ pub(super) fn check<'tcx>(
&& let QPath::Resolved(None, Path { res, .. }) = qpath && let QPath::Resolved(None, Path { res, .. }) = qpath
&& let Res::Local(hir_id) = res && let Res::Local(hir_id) = res
&& let parent = cx.tcx.parent_hir_node(*hir_id) && let parent = cx.tcx.parent_hir_node(*hir_id)
&& let Node::Local(local) = parent && let Node::LetStmt(local) = parent
{ {
if let Some(ty) = local.ty if let Some(ty) = local.ty
&& let TyKind::Path(qpath) = ty.kind && let TyKind::Path(qpath) = ty.kind
@ -275,7 +275,7 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
} }
// Local usage // Local usage
} else if let Res::Local(hir_id) = res } else if let Res::Local(hir_id) = res
&& let Node::Local(l) = cx.tcx.parent_hir_node(hir_id) && let Node::LetStmt(l) = cx.tcx.parent_hir_node(hir_id)
{ {
if let Some(e) = l.init if let Some(e) = l.init
&& is_cast_from_ty_alias(cx, e, cast_from) && is_cast_from_ty_alias(cx, e, cast_from)

View file

@ -3,7 +3,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::visitors::for_each_expr_with_closures; use clippy_utils::visitors::for_each_expr_with_closures;
use clippy_utils::{get_enclosing_block, path_to_local_id}; use clippy_utils::{get_enclosing_block, path_to_local_id};
use core::ops::ControlFlow; use core::ops::ControlFlow;
use rustc_hir::{Block, ExprKind, HirId, LangItem, Local, Node, PatKind}; use rustc_hir::{Block, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -58,7 +58,7 @@ static COLLECTIONS: [Symbol; 9] = [
]; ];
impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead { impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
// Look for local variables whose type is a container. Search surrounding bock for read access. // Look for local variables whose type is a container. Search surrounding bock for read access.
if match_acceptable_type(cx, local, &COLLECTIONS) if match_acceptable_type(cx, local, &COLLECTIONS)
&& let PatKind::Binding(_, local_id, _, _) = local.pat.kind && let PatKind::Binding(_, local_id, _, _) = local.pat.kind
@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
} }
} }
fn match_acceptable_type(cx: &LateContext<'_>, local: &Local<'_>, collections: &[rustc_span::Symbol]) -> bool { fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: &[rustc_span::Symbol]) -> bool {
let ty = cx.typeck_results().pat_ty(local.pat); let ty = cx.typeck_results().pat_ty(local.pat);
collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym)) collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym))
// String type is a lang item but not a diagnostic item for now so we need a separate check // String type is a lang item but not a diagnostic item for now so we need a separate check

View file

@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {
// Ignore function parameters // Ignore function parameters
return; return;
}, },
Node::Local(local) if local.ty.is_some() => { Node::LetStmt(local) if local.ty.is_some() => {
// Ignore let bindings with explicit type // Ignore let bindings with explicit type
return; return;
}, },

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type}; use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths}; use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
use rustc_hir::{Local, LocalSource, PatKind}; use rustc_hir::{LetStmt, LocalSource, PatKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{GenericArgKind, IsSuggestable}; use rustc_middle::ty::{GenericArgKind, IsSuggestable};
@ -138,7 +138,7 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
]; ];
impl<'tcx> LateLintPass<'tcx> for LetUnderscore { impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
if matches!(local.source, LocalSource::Normal) if matches!(local.source, LocalSource::Normal)
&& !in_external_macro(cx.tcx.sess, local.span) && !in_external_macro(cx.tcx.sess, local.span)
&& let PatKind::Wild = local.pat.kind && let PatKind::Wild = local.pat.kind

View file

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use rustc_hir::{Local, TyKind}; use rustc_hir::{LetStmt, TyKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -26,7 +26,7 @@ declare_clippy_lint! {
declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]); declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]);
impl LateLintPass<'_> for UnderscoreTyped { impl LateLintPass<'_> for UnderscoreTyped {
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) {
if !in_external_macro(cx.tcx.sess, local.span) if !in_external_macro(cx.tcx.sess, local.span)
&& let Some(ty) = local.ty // Ensure that it has a type defined && let Some(ty) = local.ty // Ensure that it has a type defined
&& let TyKind::Infer = &ty.kind // that type is '_' && let TyKind::Infer = &ty.kind // that type is '_'

View file

@ -62,7 +62,7 @@ pub(super) fn check<'tcx>(
if let Node::Pat(pat) = node if let Node::Pat(pat) = node
&& let PatKind::Binding(bind_ann, ..) = pat.kind && let PatKind::Binding(bind_ann, ..) = pat.kind
&& !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut)) && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut))
&& let Node::Local(parent_let_expr) = cx.tcx.parent_hir_node(hir_id) && let Node::LetStmt(parent_let_expr) = cx.tcx.parent_hir_node(hir_id)
&& let Some(init) = parent_let_expr.init && let Some(init) = parent_let_expr.init
{ {
match init.kind { match init.kind {

View file

@ -3,7 +3,7 @@ use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_loc
use rustc_ast::ast::{LitIntType, LitKind}; use rustc_ast::ast::{LitIntType, LitKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, walk_local, Visitor}; use rustc_hir::intravisit::{walk_expr, walk_local, Visitor};
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, PatKind}; use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
@ -141,7 +141,7 @@ impl<'a, 'tcx> InitializeVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies; type NestedFilter = nested_filter::OnlyBodies;
fn visit_local(&mut self, l: &'tcx Local<'_>) { fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
// Look for declarations of the variable // Look for declarations of the variable
if l.pat.hir_id == self.var_id if l.pat.hir_id == self.var_id
&& let PatKind::Binding(.., ident, _) = l.pat.kind && let PatKind::Binding(.., ident, _) = l.pat.kind

View file

@ -5,13 +5,13 @@ use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::needs_ordered_drop; use clippy_utils::ty::needs_ordered_drop;
use clippy_utils::visitors::any_temporaries_need_ordered_drop; use clippy_utils::visitors::any_temporaries_need_ordered_drop;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Block, Expr, ExprKind, Local, MatchSource, Pat, StmtKind}; use rustc_hir::{Block, Expr, ExprKind, LetStmt, MatchSource, Pat, StmtKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {
let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) { let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) {
([stmt, stmts @ ..], expr) => { ([stmt, stmts @ ..], expr) => {
if let StmtKind::Let(&Local { if let StmtKind::Let(&LetStmt {
init: Some(e), init: Some(e),
els: None, els: None,
.. ..

View file

@ -6,7 +6,7 @@ use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutabl
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp}; use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, LetStmt, Mutability, PatKind, UnOp};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::adjustment::Adjust;
@ -286,7 +286,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
self.cx.tcx.hir() self.cx.tcx.hir()
} }
fn visit_local(&mut self, l: &'tcx Local<'_>) { fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
if !self.after_loop { if !self.after_loop {
l.pat.each_binding_or_first(&mut |_, id, _, _| { l.pat.each_binding_or_first(&mut |_, id, _, _| {
if id == self.local_id { if id == self.local_id {

View file

@ -4,7 +4,7 @@ use clippy_utils::source::snippet_opt;
use clippy_utils::visitors::{is_local_used, local_used_once}; use clippy_utils::visitors::{is_local_used, local_used_once};
use clippy_utils::{is_trait_method, path_to_local_id}; use clippy_utils::{is_trait_method, path_to_local_id};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BindingAnnotation, ExprKind, Local, Node, PatKind, StmtKind}; use rustc_hir::{BindingAnnotation, ExprKind, LetStmt, Node, PatKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
use rustc_span::sym; use rustc_span::sym;
@ -60,7 +60,7 @@ impl ManualHashOne {
impl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]); impl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]);
impl LateLintPass<'_> for ManualHashOne { impl LateLintPass<'_> for ManualHashOne {
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) {
// `let mut hasher = seg.build_hasher();` // `let mut hasher = seg.build_hasher();`
if let PatKind::Binding(BindingAnnotation::MUT, hasher, _, None) = local.pat.kind if let PatKind::Binding(BindingAnnotation::MUT, hasher, _, None) = local.pat.kind
&& let Some(init) = local.init && let Some(init) = local.init

View file

@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
// Apply only to params or locals with annotated types // Apply only to params or locals with annotated types
match cx.tcx.parent_hir_node(hir_id) { match cx.tcx.parent_hir_node(hir_id) {
Node::Param(..) => (), Node::Param(..) => (),
Node::Local(local) => { Node::LetStmt(local) => {
let Some(ty) = local.ty else { return }; let Some(ty) = local.ty else { return };
if matches!(ty.kind, TyKind::Infer) { if matches!(ty.kind, TyKind::Infer) {
return; return;

View file

@ -2,12 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs}; use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{ByRef, ExprKind, Local, MatchSource, PatKind, QPath}; use rustc_hir::{ByRef, ExprKind, LetStmt, MatchSource, PatKind, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use super::INFALLIBLE_DESTRUCTURING_MATCH; use super::INFALLIBLE_DESTRUCTURING_MATCH;
pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool { pub(crate) fn check(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
if !local.span.from_expansion() if !local.span.from_expansion()
&& let Some(expr) = local.init && let Some(expr) = local.init
&& let ExprKind::Match(target, arms, MatchSource::Normal) = expr.kind && let ExprKind::Match(target, arms, MatchSource::Normal) = expr.kind

View file

@ -148,7 +148,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> { fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {
if let Node::Expr(parent_arm_expr) = cx.tcx.parent_hir_node(ex.hir_id) { if let Node::Expr(parent_arm_expr) = cx.tcx.parent_hir_node(ex.hir_id) {
return match cx.tcx.parent_hir_node(parent_arm_expr.hir_id) { return match cx.tcx.parent_hir_node(parent_arm_expr.hir_id) {
Node::Local(parent_let_expr) => Some(AssignmentExpr::Local { Node::LetStmt(parent_let_expr) => Some(AssignmentExpr::Local {
span: parent_let_expr.span, span: parent_let_expr.span,
pat_span: parent_let_expr.pat.span(), pat_span: parent_let_expr.pat.span(),
}), }),

View file

@ -27,7 +27,7 @@ mod wild_in_or_pats;
use clippy_config::msrvs::{self, Msrv}; use clippy_config::msrvs::{self, Msrv};
use clippy_utils::source::{snippet_opt, walk_span_to_context}; use clippy_utils::source::{snippet_opt, walk_span_to_context};
use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text}; use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text};
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat}; use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat};
use rustc_lexer::TokenKind; use rustc_lexer::TokenKind;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -1124,7 +1124,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
} }
} }
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
self.infallible_destructuring_match_linted |= self.infallible_destructuring_match_linted |=
local.els.is_none() && infallible_destructuring_match::check(cx, local); local.els.is_none() && infallible_destructuring_match::check(cx, local);
} }

View file

@ -125,7 +125,7 @@ fn strip_return<'hir>(expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {
fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>) -> bool { fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>) -> bool {
match cx.tcx.parent_hir_node(p_expr.hir_id) { match cx.tcx.parent_hir_node(p_expr.hir_id) {
// Compare match_expr ty with local in `let local = match match_expr {..}` // Compare match_expr ty with local in `let local = match match_expr {..}`
Node::Local(local) => { Node::LetStmt(local) => {
let results = cx.typeck_results(); let results = cx.typeck_results();
return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr)); return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
}, },

View file

@ -69,7 +69,7 @@ pub(super) fn check(
_ => false, _ => false,
}, },
// local binding capturing a reference // local binding capturing a reference
Node::Local(l) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..)) => { Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..)) => {
return; return;
}, },
_ => false, _ => false,

View file

@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
| ExprKind::Break(_, _) => true, | ExprKind::Break(_, _) => true,
_ => false, _ => false,
}, },
Some((Node::Stmt(_) | Node::Local(_), _)) => false, Some((Node::Stmt(_) | Node::LetStmt(_), _)) => false,
_ => true, _ => true,
}; };

View file

@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, MultiSpan}; use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node, PatKind, Stmt, StmtKind, BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, PatKind, Stmt, StmtKind,
}; };
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
@ -85,7 +85,7 @@ pub(super) fn check<'tcx>(
); );
} }
}, },
Node::Local(l) => { Node::LetStmt(l) => {
if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None) = l.pat.kind if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None) = l.pat.kind
&& let ty = cx.typeck_results().expr_ty(collect_expr) && let ty = cx.typeck_results().expr_ty(collect_expr)
&& [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList] && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList]
@ -424,7 +424,7 @@ fn get_expr_and_hir_id_from_stmt<'v>(stmt: &'v Stmt<'v>) -> Option<(&'v Expr<'v>
match stmt.kind { match stmt.kind {
StmtKind::Expr(expr) | StmtKind::Semi(expr) => Some((expr, None)), StmtKind::Expr(expr) | StmtKind::Semi(expr) => Some((expr, None)),
StmtKind::Item(..) => None, StmtKind::Item(..) => None,
StmtKind::Let(Local { init, pat, .. }) => { StmtKind::Let(LetStmt { init, pat, .. }) => {
if let PatKind::Binding(_, hir_id, ..) = pat.kind { if let PatKind::Binding(_, hir_id, ..) = pat.kind {
init.map(|init_expr| (init_expr, Some(hir_id))) init.map(|init_expr| (init_expr, Some(hir_id)))
} else { } else {

View file

@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver
&& let Node::Expr(unwrap_call_expr) = cx.tcx.parent_hir_node(expr.hir_id) && let Node::Expr(unwrap_call_expr) = cx.tcx.parent_hir_node(expr.hir_id)
&& is_unwrap_call(cx, unwrap_call_expr) && is_unwrap_call(cx, unwrap_call_expr)
&& let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id) && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id)
&& let Node::Local(local) = parent && let Node::LetStmt(local) = parent
&& let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id) && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)
&& let Some((local, _)) = mir && let Some((local, _)) = mir
.local_decls .local_decls

View file

@ -8,7 +8,7 @@ use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths}
use core::ops::ControlFlow; use core::ops::ControlFlow;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Expr, ExprKind, HirId, LangItem, Local, MatchSource, Node, Pat, PatKind, QPath, Stmt, StmtKind, BindingAnnotation, Expr, ExprKind, HirId, LangItem, LetStmt, MatchSource, Node, Pat, PatKind, QPath, Stmt, StmtKind,
}; };
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
@ -128,7 +128,7 @@ fn check_manual_split_once_indirect(
) -> Option<()> { ) -> Option<()> {
let ctxt = expr.span.ctxt(); let ctxt = expr.span.ctxt();
let mut parents = cx.tcx.hir().parent_iter(expr.hir_id); let mut parents = cx.tcx.hir().parent_iter(expr.hir_id);
if let (_, Node::Local(local)) = parents.next()? if let (_, Node::LetStmt(local)) = parents.next()?
&& let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind && let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind
&& let (iter_stmt_id, Node::Stmt(_)) = parents.next()? && let (iter_stmt_id, Node::Stmt(_)) = parents.next()?
&& let (_, Node::Block(enclosing_block)) = parents.next()? && let (_, Node::Block(enclosing_block)) = parents.next()?
@ -198,7 +198,7 @@ fn indirect_usage<'tcx>(
binding: HirId, binding: HirId,
ctxt: SyntaxContext, ctxt: SyntaxContext,
) -> Option<IndirectUsage<'tcx>> { ) -> Option<IndirectUsage<'tcx>> {
if let StmtKind::Let(&Local { if let StmtKind::Let(&LetStmt {
pat: Pat { pat: Pat {
kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None), kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None),
.. ..

View file

@ -20,7 +20,7 @@ fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
// some common cases where turbofish isn't needed: // some common cases where turbofish isn't needed:
// - assigned to a local variable with a type annotation // - assigned to a local variable with a type annotation
if let hir::Node::Local(local) = parent if let hir::Node::LetStmt(local) = parent
&& local.ty.is_some() && local.ty.is_some()
{ {
return false; return false;

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_note}; use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id}; use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Local, Node, Stmt, StmtKind}; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, LetStmt, Node, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
match stmt.kind { match stmt.kind {
StmtKind::Let(local) => { StmtKind::Let(local) => {
if let Local { init: Some(e), .. } = local { if let LetStmt { init: Some(e), .. } = local {
DivergenceVisitor { cx }.visit_expr(e); DivergenceVisitor { cx }.visit_expr(e);
} }
}, },

View file

@ -121,7 +121,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
} }
} }
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) { fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::LetStmt<'_>) {
if let hir::PatKind::Wild = local.pat.kind { if let hir::PatKind::Wild = local.pat.kind {
return; return;
} }

View file

@ -6,7 +6,7 @@ use clippy_utils::visitors::{for_each_expr, for_each_expr_with_closures, is_loca
use core::ops::ControlFlow; use core::ops::ControlFlow;
use rustc_errors::{Applicability, MultiSpan}; use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Block, Expr, ExprKind, HirId, Local, LocalSource, MatchSource, Node, Pat, PatKind, Stmt, BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt,
StmtKind, StmtKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -237,7 +237,7 @@ fn first_usage<'tcx>(
}) })
} }
fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &Local<'_>) -> Option<String> { fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<String> {
let span = local.span.with_hi(match local.ty { let span = local.span.with_hi(match local.ty {
// let <pat>: <ty>; // let <pat>: <ty>;
// ~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~
@ -252,7 +252,7 @@ fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &Local<'_>) -> O
fn check<'tcx>( fn check<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
local: &'tcx Local<'tcx>, local: &'tcx LetStmt<'tcx>,
local_stmt: &'tcx Stmt<'tcx>, local_stmt: &'tcx Stmt<'tcx>,
block: &'tcx Block<'tcx>, block: &'tcx Block<'tcx>,
binding_id: HirId, binding_id: HirId,
@ -363,9 +363,9 @@ fn check<'tcx>(
} }
impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit { impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
let mut parents = cx.tcx.hir().parent_iter(local.hir_id); let mut parents = cx.tcx.hir().parent_iter(local.hir_id);
if let Local { if let LetStmt {
init: None, init: None,
pat: pat:
&Pat { &Pat {

View file

@ -604,7 +604,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
match get_expr_use_or_unification_node(self.cx.tcx, e) { match get_expr_use_or_unification_node(self.cx.tcx, e) {
Some((Node::Stmt(_), _)) => (), Some((Node::Stmt(_), _)) => (),
Some((Node::Local(l), _)) => { Some((Node::LetStmt(l), _)) => {
// Only trace simple bindings. e.g `let x = y;` // Only trace simple bindings. e.g `let x = y;`
if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind { if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind {
self.bindings.insert(id, args_idx); self.bindings.insert(id, args_idx);

View file

@ -14,7 +14,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Block, ByRef, Expr, ExprKind, Local, Node, PatKind, PathSegment, QPath, Stmt, StmtKind, BindingAnnotation, Block, ByRef, Expr, ExprKind, LetStmt, Node, PatKind, PathSegment, QPath, Stmt, StmtKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
@ -109,7 +109,7 @@ fn find_let_else_ret_expression<'hir>(block: &'hir Block<'hir>) -> Option<&'hir
} }
fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
if let StmtKind::Let(Local { if let StmtKind::Let(LetStmt {
pat, pat,
init: Some(init_expr), init: Some(init_expr),
els: Some(els), els: Some(els),

View file

@ -3,7 +3,7 @@ use clippy_utils::get_enclosing_block;
use clippy_utils::higher::{get_vec_init_kind, VecInitKind}; use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use hir::{Expr, ExprKind, HirId, Local, PatKind, PathSegment, QPath, StmtKind}; use hir::{Expr, ExprKind, HirId, LetStmt, PatKind, PathSegment, QPath, StmtKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
} }
if let StmtKind::Let(local) = stmt.kind if let StmtKind::Let(local) = stmt.kind
&& let Local { && let LetStmt {
pat, init: Some(init), .. pat, init: Some(init), ..
} = local } = local
&& let PatKind::Binding(_, id, ident, _) = pat.kind && let PatKind::Binding(_, id, ident, _) = pat.kind

View file

@ -3,7 +3,7 @@ use clippy_utils::is_from_proc_macro;
use clippy_utils::ty::needs_ordered_drop; use clippy_utils::ty::needs_ordered_drop;
use rustc_ast::Mutability; use rustc_ast::Mutability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, Local, Node, Pat, PatKind, QPath}; use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath};
use rustc_hir_typeck::expr_use_visitor::PlaceBase; use rustc_hir_typeck::expr_use_visitor::PlaceBase;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -47,7 +47,7 @@ declare_clippy_lint! {
declare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]); declare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]);
impl<'tcx> LateLintPass<'tcx> for RedundantLocals { impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
if !local.span.is_desugaring(DesugaringKind::Async) if !local.span.is_desugaring(DesugaringKind::Async)
// the pattern is a single by-value binding // the pattern is a single by-value binding
&& let PatKind::Binding(BindingAnnotation(ByRef::No, mutability), _, ident, None) = local.pat.kind && let PatKind::Binding(BindingAnnotation(ByRef::No, mutability), _, ident, None) = local.pat.kind

View file

@ -131,7 +131,7 @@ fn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option<hir::PrimTy> {
} }
impl LateLintPass<'_> for RedundantTypeAnnotations { impl LateLintPass<'_> for RedundantTypeAnnotations {
fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::Local<'tcx>) { fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::LetStmt<'tcx>) {
if !is_lint_allowed(cx, REDUNDANT_TYPE_ANNOTATIONS, local.hir_id) if !is_lint_allowed(cx, REDUNDANT_TYPE_ANNOTATIONS, local.hir_id)
// type annotation part // type annotation part
&& !local.span.from_expansion() && !local.span.from_expansion()

View file

@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
use clippy_utils::{is_from_proc_macro, path_to_local_id}; use clippy_utils::{is_from_proc_macro, path_to_local_id};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Local, PatKind, QPath, Stmt, StmtKind}; use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
self.searcher = None; self.searcher = None;
} }
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
if let Some(init_expr) = local.init if let Some(init_expr) = local.init
&& let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind && let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind
&& !in_external_macro(cx.sess(), local.span) && !in_external_macro(cx.sess(), local.span)

View file

@ -241,7 +241,7 @@ fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'
ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some(e), ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some(e),
_ => None, _ => None,
}, },
Node::Local(local) => local.init, Node::LetStmt(local) => local.init,
_ => None, _ => None,
}; };
return init; return init;

View file

@ -159,7 +159,7 @@ fn all_bindings_are_for_conv<'tcx>(
.iter() .iter()
.map(|node| match node { .map(|node| match node {
Node::Pat(pat) => kind.eq(&pat.kind).then_some(pat.hir_id), Node::Pat(pat) => kind.eq(&pat.kind).then_some(pat.hir_id),
Node::Local(l) => Some(l.hir_id), Node::LetStmt(l) => Some(l.hir_id),
_ => None, _ => None,
}) })
.all_equal() .all_equal()
@ -170,7 +170,7 @@ fn all_bindings_are_for_conv<'tcx>(
&& local_parents.first().is_some_and(|node| { && local_parents.first().is_some_and(|node| {
let Some(ty) = match node { let Some(ty) = match node {
Node::Pat(pat) => Some(pat.hir_id), Node::Pat(pat) => Some(pat.hir_id),
Node::Local(l) => Some(l.hir_id), Node::LetStmt(l) => Some(l.hir_id),
_ => None, _ => None,
} }
.map(|hir_id| cx.typeck_results().node_type(hir_id)) else { .map(|hir_id| cx.typeck_results().node_type(hir_id)) else {

View file

@ -12,7 +12,7 @@ mod vec_box;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{ use rustc_hir::{
Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, Local, MutTy, QPath, TraitItem, Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitItem,
TraitItemKind, TyKind, TraitItemKind, TyKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -425,7 +425,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
} }
} }
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
if let Some(ty) = local.ty { if let Some(ty) = local.ty {
self.check_ty( self.check_ty(
cx, cx,

View file

@ -158,7 +158,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
} }
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) {
let (hir::StmtKind::Let(&hir::Local { init: Some(expr), .. }) let (hir::StmtKind::Let(&hir::LetStmt { init: Some(expr), .. })
| hir::StmtKind::Expr(expr) | hir::StmtKind::Expr(expr)
| hir::StmtKind::Semi(expr)) = stmt.kind | hir::StmtKind::Semi(expr)) = stmt.kind
else { else {
@ -342,7 +342,7 @@ fn block_parents_have_safety_comment(
) -> bool { ) -> bool {
let (span, hir_id) = match cx.tcx.parent_hir_node(id) { let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) { Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id), Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..), kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
span, span,
@ -358,12 +358,12 @@ fn block_parents_have_safety_comment(
}, },
Node::Stmt(hir::Stmt { Node::Stmt(hir::Stmt {
kind: kind:
hir::StmtKind::Let(hir::Local { span, hir_id, .. }) hir::StmtKind::Let(hir::LetStmt { span, hir_id, .. })
| hir::StmtKind::Expr(hir::Expr { span, hir_id, .. }) | hir::StmtKind::Expr(hir::Expr { span, hir_id, .. })
| hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }), | hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }),
.. ..
}) })
| Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id), | Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..), kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
span, span,
@ -603,7 +603,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
for (_, node) in map.parent_iter(body.hir_id) { for (_, node) in map.parent_iter(body.hir_id) {
match node { match node {
Node::Expr(e) => span = e.span, Node::Expr(e) => span = e.span,
Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (), Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..), kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
.. ..

View file

@ -4,14 +4,14 @@ use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source};
use core::ops::ControlFlow; use core::ops::ControlFlow;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, MatchSource, Node, PatKind, QPath, TyKind}; use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::{in_external_macro, is_from_async_await}; use rustc_middle::lint::{in_external_macro, is_from_async_await};
use rustc_middle::ty; use rustc_middle::ty;
use super::LET_UNIT_VALUE; use super::LET_UNIT_VALUE;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
// skip `let () = { ... }` // skip `let () = { ... }`
if let PatKind::Tuple(fields, ..) = local.pat.kind if let PatKind::Tuple(fields, ..) = local.pat.kind
&& fields.is_empty() && fields.is_empty()
@ -102,7 +102,7 @@ fn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -
return false; return false;
} }
while let Some(id) = locals_to_check.pop() { while let Some(id) = locals_to_check.pop() {
if let Node::Local(l) = cx.tcx.parent_hir_node(id) { if let Node::LetStmt(l) = cx.tcx.parent_hir_node(id) {
if !l.ty.map_or(true, |ty| matches!(ty.kind, TyKind::Infer)) { if !l.ty.map_or(true, |ty| matches!(ty.kind, TyKind::Infer)) {
return false; return false;
} }

View file

@ -3,7 +3,7 @@ mod unit_arg;
mod unit_cmp; mod unit_cmp;
mod utils; mod utils;
use rustc_hir::{Expr, Local}; use rustc_hir::{Expr, LetStmt};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -99,7 +99,7 @@ declare_clippy_lint! {
declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]); declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
impl<'tcx> LateLintPass<'tcx> for UnitTypes { impl<'tcx> LateLintPass<'tcx> for UnitTypes {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
let_unit_value::check(cx, local); let_unit_value::check(cx, local);
} }

View file

@ -3,7 +3,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators}; use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators};
use rustc_ast::Mutability; use rustc_ast::Mutability;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind}; use rustc_hir::{Block, Expr, ExprKind, HirId, LetStmt, Node, PatKind, PathSegment, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -190,7 +190,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
}, },
} }
}, },
Node::Local(Local { init: Some(init), .. }) => { Node::LetStmt(LetStmt { init: Some(init), .. }) => {
if arg_is_mut_peekable(self.cx, init) { if arg_is_mut_peekable(self.cx, init) {
self.found_peek_call = true; self.found_peek_call = true;
} }

View file

@ -1006,7 +1006,7 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -
fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> { fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> {
match cx.tcx.parent_hir_node(hir_id) { match cx.tcx.parent_hir_node(hir_id) {
hir::Node::Local(local) => Some(local), hir::Node::LetStmt(local) => Some(local),
hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id), hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id),
_ => None, _ => None,
} }

View file

@ -217,7 +217,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
match peel_hir_expr_refs(expr).0.kind { match peel_hir_expr_refs(expr).0.kind {
ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) { ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
Res::Local(hir_id) => { Res::Local(hir_id) => {
if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) { if let Node::LetStmt(Local { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) {
path_to_matched_type(cx, init) path_to_matched_type(cx, init)
} else { } else {
None None

View file

@ -9,7 +9,7 @@ use clippy_utils::ty::is_copy;
use clippy_utils::visitors::for_each_local_use_after_expr; use clippy_utils::visitors::for_each_local_use_after_expr;
use clippy_utils::{get_parent_expr, higher, is_trait_method}; use clippy_utils::{get_parent_expr, higher, is_trait_method};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Local, Mutability, Node, Pat, PatKind}; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
match cx.tcx.parent_hir_node(expr.hir_id) { match cx.tcx.parent_hir_node(expr.hir_id) {
// search for `let foo = vec![_]` expressions where all uses of `foo` // search for `let foo = vec![_]` expressions where all uses of `foo`
// adjust to slices or call a method that exist on slices (e.g. len) // adjust to slices or call a method that exist on slices (e.g. len)
Node::Local(Local { Node::LetStmt(LetStmt {
ty: None, ty: None,
pat: pat:
Pat { Pat {
@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
} }
}, },
// if the local pattern has a specified type, do not lint. // if the local pattern has a specified type, do not lint.
Node::Local(Local { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => { Node::LetStmt(LetStmt { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => {
self.span_to_lint_map.insert(callsite, None); self.span_to_lint_map.insert(callsite, None);
}, },
// search for `for _ in vec![...]` // search for `for _ in vec![...]`

View file

@ -7,7 +7,7 @@ use core::ops::ControlFlow;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Block, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp, BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp,
}; };
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
self.searcher = None; self.searcher = None;
} }
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
if let Some(init_expr) = local.init if let Some(init_expr) = local.init
&& let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind && let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind
&& !in_external_macro(cx.sess(), local.span) && !in_external_macro(cx.sess(), local.span)

View file

@ -78,7 +78,7 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id); let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id);
let return_type = cx.typeck_results().expr_ty(expr); let return_type = cx.typeck_results().expr_ty(expr);
if let Node::Local(l) = parent_hir_node { if let Node::LetStmt(l) = parent_hir_node {
array_span_lint( array_span_lint(
cx, cx,
l.span, l.span,

View file

@ -99,7 +99,7 @@ use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::{ use rustc_hir::{
self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr, self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr,
ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item,
ItemKind, LangItem, Local, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy,
QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
}; };
use rustc_lexer::{tokenize, TokenKind}; use rustc_lexer::{tokenize, TokenKind};
@ -184,7 +184,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>> { pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
if let Node::Pat(pat) = cx.tcx.hir_node(hir_id) if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
&& matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)) && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
&& let Node::Local(local) = cx.tcx.parent_hir_node(hir_id) && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id)
{ {
return local.init; return local.init;
} }
@ -1079,7 +1079,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
}, },
_ => break, _ => break,
}, },
Node::Local(l) => match pat_capture_kind(cx, l.pat) { Node::LetStmt(l) => match pat_capture_kind(cx, l.pat) {
CaptureKind::Value => break, CaptureKind::Value => break,
capture @ CaptureKind::Ref(_) => return capture, capture @ CaptureKind::Ref(_) => return capture,
}, },
@ -1357,7 +1357,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
ExprKind::Closure { .. } | ExprKind::Loop(..) => return Some(e), ExprKind::Closure { .. } | ExprKind::Loop(..) => return Some(e),
_ => (), _ => (),
}, },
Node::Stmt(_) | Node::Block(_) | Node::Local(_) | Node::Arm(_) => (), Node::Stmt(_) | Node::Block(_) | Node::LetStmt(_) | Node::Arm(_) => (),
_ => break, _ => break,
} }
} }
@ -1462,7 +1462,7 @@ pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
let mut child_id = expr.hir_id; let mut child_id = expr.hir_id;
for (parent_id, node) in tcx.hir().parent_iter(child_id) { for (parent_id, node) in tcx.hir().parent_iter(child_id) {
if let Node::Local(Local { if let Node::LetStmt(LetStmt {
init: Some(init), init: Some(init),
els: Some(els), els: Some(els),
.. ..
@ -1482,7 +1482,7 @@ pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
let mut child_id = expr.hir_id; let mut child_id = expr.hir_id;
for (parent_id, node) in tcx.hir().parent_iter(child_id) { for (parent_id, node) in tcx.hir().parent_iter(child_id) {
if let Node::Local(Local { els: Some(els), .. }) = node if let Node::LetStmt(LetStmt { els: Some(els), .. }) = node
&& els.hir_id == child_id && els.hir_id == child_id
{ {
return true; return true;
@ -2158,7 +2158,7 @@ pub fn is_expr_used_or_unified(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
Node::Stmt(Stmt { Node::Stmt(Stmt {
kind: StmtKind::Expr(_) kind: StmtKind::Expr(_)
| StmtKind::Semi(_) | StmtKind::Semi(_)
| StmtKind::Let(Local { | StmtKind::Let(LetStmt {
pat: Pat { pat: Pat {
kind: PatKind::Wild, kind: PatKind::Wild,
.. ..
@ -2639,7 +2639,7 @@ pub struct ExprUseCtxt<'tcx> {
/// The node which consumes a value. /// The node which consumes a value.
pub enum ExprUseNode<'tcx> { pub enum ExprUseNode<'tcx> {
/// Assignment to, or initializer for, a local /// Assignment to, or initializer for, a local
Local(&'tcx Local<'tcx>), LetStmt(&'tcx LetStmt<'tcx>),
/// Initializer for a const or static item. /// Initializer for a const or static item.
ConstStatic(OwnerId), ConstStatic(OwnerId),
/// Implicit or explicit return from a function. /// Implicit or explicit return from a function.
@ -2671,7 +2671,7 @@ impl<'tcx> ExprUseNode<'tcx> {
/// Gets the needed type as it's defined without any type inference. /// Gets the needed type as it's defined without any type inference.
pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> { pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> {
match *self { match *self {
Self::Local(Local { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)), Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)),
Self::ConstStatic(id) => Some(DefinedTy::Mir( Self::ConstStatic(id) => Some(DefinedTy::Mir(
cx.param_env cx.param_env
.and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())), .and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())),
@ -2731,7 +2731,7 @@ impl<'tcx> ExprUseNode<'tcx> {
let sig = cx.tcx.fn_sig(id).skip_binder(); let sig = cx.tcx.fn_sig(id).skip_binder();
Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i)))) Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i))))
}, },
Self::Local(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None, Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None,
} }
} }
} }
@ -2770,7 +2770,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio
.continue_value() .continue_value()
.map(|(use_node, child_id)| { .map(|(use_node, child_id)| {
let node = match use_node { let node = match use_node {
Node::Local(l) => ExprUseNode::Local(l), Node::LetStmt(l) => ExprUseNode::LetStmt(l),
Node::ExprField(field) => ExprUseNode::Field(field), Node::ExprField(field) => ExprUseNode::Field(field),
Node::Item(&Item { Node::Item(&Item {
@ -3158,7 +3158,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
} }
} }
fn visit_local(&mut self, l: &'tcx Local<'_>) { fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
if let Some(e) = l.init { if let Some(e) = l.init {
self.visit_expr(e); self.visit_expr(e);
} }

View file

@ -242,7 +242,7 @@ fn path_segment_certainty(
Node::Param(..) => Certainty::Certain(None), Node::Param(..) => Certainty::Certain(None),
// A local's type is certain if its type annotation is certain or it has an initializer whose // A local's type is certain if its type annotation is certain or it has an initializer whose
// type is certain. // type is certain.
Node::Local(local) => { Node::LetStmt(local) => {
let lhs = local.ty.map_or(Certainty::Uncertain, |ty| type_certainty(cx, ty)); let lhs = local.ty.map_or(Certainty::Uncertain, |ty| type_certainty(cx, ty));
let rhs = local let rhs = local
.init .init

View file

@ -1,6 +1,5 @@
//@ unit-test: DataflowConstProp //@ unit-test: DataflowConstProp
//@ compile-flags: -Zmir-enable-passes=+GVN,+Inline //@ compile-flags: -Zmir-enable-passes=+GVN,+Inline
//@ ignore-debug assertions change the output MIR
// EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View file

@ -1,6 +1,5 @@
// skip-filecheck // skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ compile-flags: --crate-type lib -Cdebug-assertions=no
#![feature(flt2dec)] #![feature(flt2dec)]

View file

@ -2,7 +2,6 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(unchecked_shifts)] #![feature(unchecked_shifts)]
//@ ignore-debug: the debug assertions prevent the inlining we are testing for
//@ compile-flags: -Zmir-opt-level=2 -Zinline-mir //@ compile-flags: -Zmir-opt-level=2 -Zinline-mir
// EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff // EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff

View file

@ -1,8 +1,7 @@
#![crate_type = "lib"] #![crate_type = "lib"]
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ ignore-debug: the debug assertions prevent the inlining we are testing for //@ compile-flags: -Zmir-opt-level=2 -Zinline-mir
//@ compile-flags: -Zmir-opt-level=2 -Zinline-mir -Cdebug-assertions=no
// EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff // EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff
// EMIT_MIR unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir // EMIT_MIR unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir

Some files were not shown because too many files have changed in this diff Show more