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
if [[ "$STATE" == "OPEN" && "$WAITING_ON_BORS" == "true" ]]; then
exit 1
gh run cancel ${{ github.run_id }}
fi
update:
@ -65,7 +65,10 @@ jobs:
- name: cargo update
# 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
uses: actions/upload-artifact@v3
with:
@ -131,7 +134,7 @@ jobs:
# Exit with error if PR is closed
STATE=$(gh pr view cargo_update --repo $GITHUB_REPOSITORY --json state --jq '.state')
if [[ "$STATE" != "OPEN" ]]; then
exit 1
gh run cancel ${{ github.run_id }}
fi
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)
}
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
.ty
.as_ref()
@ -97,7 +97,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let span = self.lower_span(l.span);
let source = hir::LocalSource::Normal;
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 {

View File

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

View File

@ -2341,7 +2341,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
debug_assert!(!a.is_empty());
self.attrs.insert(hir_id.local_id, a);
}
let local = hir::Local {
let local = hir::LetStmt {
hir_id,
init,
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,
// 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
&& let hir::PatKind::Binding(..) = pat.kind
&& 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) {
let e = match node {
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![] };
finder.visit_block(els);
if !finder.found_breaks.is_empty() {
@ -2124,7 +2124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
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, _), .. } =
local.pat
&& let Some(init) = local.init

View File

@ -558,7 +558,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
hir::intravisit::walk_stmt(self, stmt);
let expr = match stmt.kind {
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;
}
@ -737,7 +737,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&& let body = self.infcx.tcx.hir().body(body_id)
&& let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value()
&& 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(_, _), .. },
..
})
@ -1170,7 +1170,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
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());
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_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
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::ty::layout::LayoutOf;
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)
}
/// 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")]
pub fn eval_to_const_value_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>,

View File

@ -2,10 +2,11 @@
use rustc_middle::mir;
use rustc_middle::mir::interpret::InterpErrorInfo;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::{self, Ty};
use rustc_middle::query::{Key, TyCtxtAt};
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 error;
@ -77,3 +78,21 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
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 => {
// 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.
// But what if the data stored here does not actually encode
// 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))
}
/// Computes the tag value and its field number (if any) of a given variant
/// of type `ty`.
/// Computes how to write the tag of a given variant of enum `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(
&self,
ty: Ty<'tcx>,

View File

@ -1220,7 +1220,7 @@ pub struct Stmt<'hir> {
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum StmtKind<'hir> {
/// A local (`let`) binding.
Let(&'hir Local<'hir>),
Let(&'hir LetStmt<'hir>),
/// An item binding.
Item(ItemId),
@ -1234,7 +1234,7 @@ pub enum StmtKind<'hir> {
/// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Local<'hir> {
pub struct LetStmt<'hir> {
pub pat: &'hir Pat<'hir>,
/// Type annotation, if any (otherwise the type will be inferred).
pub ty: Option<&'hir Ty<'hir>>,
@ -1264,7 +1264,7 @@ pub struct Arm<'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.
///
/// 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>),
/// 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(..)`.
Let(&'hir LetExpr<'hir>),
/// An `if` block, with an optional else block.
@ -3529,7 +3529,7 @@ pub enum Node<'hir> {
PatField(&'hir PatField<'hir>),
Arm(&'hir Arm<'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
/// with synthesized constructors.
Ctor(&'hir VariantData<'hir>),
@ -3585,7 +3585,7 @@ impl<'hir> Node<'hir> {
| Node::Ctor(..)
| Node::Pat(..)
| Node::Arm(..)
| Node::Local(..)
| Node::LetStmt(..)
| Node::Crate(..)
| Node::Ty(..)
| Node::TraitRef(..)
@ -3757,7 +3757,7 @@ impl<'hir> Node<'hir> {
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
expect_arm, &'hir Arm<'hir>, Node::Arm(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_lifetime, &'hir Lifetime, Node::Lifetime(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!(Item<'_>, 88);
static_assert_size!(ItemKind<'_>, 56);
static_assert_size!(Local<'_>, 64);
static_assert_size!(LetStmt<'_>, 64);
static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72);
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 {
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)
}
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()
}
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
// dominates the local's definition.
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() {
debug_assert!(
!collector.types.is_empty(),
"expect >0 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
if !unnormalized_trait_sig.output().references_error() && collector.types.is_empty() {
tcx.dcx().delayed_bug(
"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::def_id::DefId;
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_middle::middle::region::*;
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() {
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.
// First we take a checkpoint of the current scope context here.
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>) {
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)
}
}

View File

@ -113,7 +113,7 @@ impl<'a> State<'a> {
// `hir_map` to reconstruct their full structure for pretty
// printing.
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::WhereBoundPredicate(pred) => {
self.print_formal_generic_params(pred.bound_generic_params);
@ -1544,7 +1544,7 @@ impl<'a> State<'a> {
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);
if let Some(ty) = loc.ty {
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()));
}
None

View File

@ -299,8 +299,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false;
};
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::Local(hir::Local { init: Some(init), .. }) => (init.hir_id, Some(*init)),
hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init, .. }) => (ty.hir_id, *init),
hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => (init.hir_id, Some(*init)),
_ => return false,
};
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>>,
) {
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 =>
{
// Point at `let` assignment type.
@ -724,11 +724,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
primary_span = pat.span;
secondary_span = pat.span;
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;
post_message = " type";
}
hir::Node::Local(hir::Local { init: Some(init), .. }) => {
hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => {
primary_span = init.span;
post_message = " value";
}

View File

@ -1451,7 +1451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
});
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, _, _), .. }),
)) = parent_node
else {

View File

@ -371,7 +371,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
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, |_| {})
}

View File

@ -1601,7 +1601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
/// 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());
if local.pat.is_never_pattern() {
self.diverges.set(Diverges::Always {
@ -1789,7 +1789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
[
hir::Stmt {
kind:
hir::StmtKind::Let(hir::Local {
hir::StmtKind::Let(hir::LetStmt {
source:
hir::LocalSource::AssignDesugar(_),
..

View File

@ -317,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
expr_id = parent_id;
}
Node::Local(local) => {
Node::LetStmt(local) => {
if let Some(mut ty) = local.ty {
while let Some(index) = tuple_indexes.pop() {
match ty.kind {
@ -1348,7 +1348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// ++++++++++
// since the user probably just misunderstood how `let else`
// 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, _, _) =
&local.pat.kind
&& 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) {
// 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)
}
// When `expr` is more complex like a tuple
@ -1757,7 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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)
else {
return expr;
@ -1791,7 +1791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } =
call_expr_path
&& 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)
&& let Expr {
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 {
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)
else {
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.
pub(super) struct Declaration<'a> {
@ -41,9 +41,9 @@ pub(super) struct Declaration<'a> {
pub origin: DeclOrigin<'a>,
}
impl<'a> From<&'a hir::Local<'a>> for Declaration<'a> {
fn from(local: &'a hir::Local<'a>) -> Self {
let hir::Local { hir_id, pat, ty, span, init, els, source: _ } = *local;
impl<'a> From<&'a hir::LetStmt<'a>> for Declaration<'a> {
fn from(local: &'a hir::LetStmt<'a>) -> Self {
let hir::LetStmt { hir_id, pat, ty, span, init, els, source: _ } = *local;
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> {
// 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());
intravisit::walk_local(self, local)
}

View File

@ -2163,7 +2163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match (filename, parent_node) {
(
FileName::Real(_),
Node::Local(hir::Local {
Node::LetStmt(hir::LetStmt {
source: hir::LocalSource::Normal,
ty,
..
@ -2218,7 +2218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
impl<'v> Visitor<'v> for LetVisitor {
type Result = ControlFlow<Option<&'v hir::Expr<'v>>>;
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
&& ident.name == self.ident_name
{

View File

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

View File

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

View File

@ -351,7 +351,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
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);
let var_ty = self.fcx.local_ty(l.span, l.hir_id);
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.
if let hir::Stmt {
kind:
hir::StmtKind::Let(hir::Local {
hir::StmtKind::Let(hir::LetStmt {
init: Some(hir::Expr { span: init_span, .. }),
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_id::{DefId, LocalDefId};
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::infer::unify_key::{
ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue,
@ -1122,7 +1122,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
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);
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 hir::def::CtorKind;
use hir::intravisit::{walk_expr, walk_stmt, Visitor};
use hir::{Local, QPath};
use hir::{LetStmt, QPath};
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diag};
use rustc_hir as hir;
@ -321,7 +321,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& let Some(expr) = block.expr
&& let hir::ExprKind::Path(QPath::Resolved(_, Path { res, .. })) = expr.kind
&& 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>>) {
match expr.kind {
@ -585,7 +586,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
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,
pat: hir::Pat { .. },
ty: None,

View File

@ -937,7 +937,7 @@ impl<'tcx> LateContext<'tcx> {
}
&& let Some(init) = match parent_node {
hir::Node::Expr(expr) => Some(expr),
hir::Node::Local(hir::Local { init, .. }) => *init,
hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
_ => None,
}
{
@ -982,7 +982,7 @@ impl<'tcx> LateContext<'tcx> {
}
&& let Some(init) = match parent_node {
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::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => {
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| {
lint_callback!(cx, check_local, 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 {
#[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) {
return;
}

View File

@ -354,7 +354,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
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);
intravisit::walk_local(self, l);
}
@ -428,7 +428,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'
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);
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_item(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_post(a: &'tcx rustc_hir::Block<'tcx>);
fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);

View File

@ -46,7 +46,7 @@ declare_lint! {
declare_lint_pass!(UnitBindings => [UNIT_BINDINGS]);
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:
// - explicitly ascribes a type to the pattern
// - explicitly wrote `let pat = ();`

View File

@ -567,7 +567,7 @@ impl<'hir> Map<'hir> {
}
// Ignore `return`s on the first iteration
Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. })
| Node::Local(_) => {
| Node::LetStmt(_) => {
return None;
}
_ => {}
@ -906,7 +906,7 @@ impl<'hir> Map<'hir> {
Node::Lifetime(lifetime) => lifetime.ident.span,
Node::GenericParam(param) => param.span,
Node::Infer(i) => i.span,
Node::Local(local) => local.span,
Node::LetStmt(local) => local.span,
Node::Crate(item) => item.spans.inner_span,
Node::WhereBoundPredicate(pred) => pred.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::Block(_) => node_str("block"),
Node::Infer(_) => node_str("infer"),
Node::Local(_) => node_str("local"),
Node::LetStmt(_) => node_str("local"),
Node::Ctor(ctor) => format!(
"{id} (ctor {})",
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)
}
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);
hir_visit::walk_local(self, l)
}

View File

@ -342,7 +342,7 @@ impl<'tcx> 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);
if local.els.is_some() {
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
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| {
if local.init.is_some() {
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);
}
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 self.check_expr_pat_type(init.hir_id, init.span) {
// Do not report duplicate errors for `let x = y`.

View File

@ -44,6 +44,10 @@ pub struct FieldInfo {
pub offset: u64,
pub size: 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)]
@ -192,7 +196,7 @@ impl CodeStats {
fields.sort_by_key(|f| (f.offset, f.size));
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 {
let pad = offset - min_offset;
@ -201,21 +205,27 @@ impl CodeStats {
if offset < min_offset {
// If this happens it's probably a union.
println!(
print!(
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \
offset: {offset} bytes, \
alignment: {align} bytes"
);
} 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 {
// Include field alignment in output only if it caused padding injection
println!(
print!(
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \
alignment: {align} bytes"
);
}
if let Some(type_name) = type_name {
println!(", type: {type_name}");
} else {
println!();
}
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
// 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,
}
}
@ -930,7 +930,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
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)
else {
return;
@ -1562,7 +1562,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let Res::Local(hir_id) = path.res
&& 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 Some(binding_expr) = local.init
{
@ -2966,7 +2966,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.downgrade_to_delayed_bug();
}
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(
ty.span.shrink_to_lo(),
"consider borrowing here",
@ -2975,7 +2975,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
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, .. }),
..
}) => {
@ -3867,7 +3867,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: Res::Local(hir_id), .. } = path
&& 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
{
// 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);
// 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
{
// ...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);
// 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
{
// ...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::{self, AdtDef, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use rustc_span::sym;
use rustc_span::symbol::Symbol;
use rustc_target::abi::*;
@ -1007,6 +1008,7 @@ fn variant_info_for_adt<'tcx>(
offset: offset.bytes(),
size: field_layout.size.bytes(),
align: field_layout.align.abi.bytes(),
type_name: None,
}
})
.collect();
@ -1090,6 +1092,7 @@ fn variant_info_for_coroutine<'tcx>(
offset: offset.bytes(),
size: field_layout.size.bytes(),
align: field_layout.align.abi.bytes(),
type_name: None,
}
})
.collect();
@ -1104,19 +1107,24 @@ fn variant_info_for_coroutine<'tcx>(
.iter()
.enumerate()
.map(|(field_idx, local)| {
let field_name = coroutine.field_names[*local];
let field_layout = variant_layout.field(cx, field_idx);
let offset = variant_layout.fields.offset(field_idx);
// The struct is as large as the last field's end
variant_size = variant_size.max(offset + field_layout.size);
FieldInfo {
kind: FieldKind::CoroutineLocal,
name: coroutine.field_names[*local].unwrap_or(Symbol::intern(&format!(
name: field_name.unwrap_or(Symbol::intern(&format!(
".coroutine_field{}",
local.as_usize()
))),
offset: offset.bytes(),
size: field_layout.size.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())

View File

@ -190,7 +190,6 @@
#![feature(ptr_metadata)]
#![feature(set_ptr_value)]
#![feature(slice_ptr_get)]
#![feature(slice_split_at_unchecked)]
#![feature(split_at_checked)]
#![feature(str_internals)]
#![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 {
formatter.write_str("panicked at ")?;
self.location.fmt(formatter)?;
formatter.write_str(":")?;
if let Some(message) = self.message {
formatter.write_str(":\n")?;
formatter.write_str("\n")?;
formatter.write_fmt(*message)?;
} else if let Some(payload) = self.payload.downcast_ref::<&'static str>() {
formatter.write_str(":\n")?;
formatter.write_str("\n")?;
formatter.write_str(payload)?;
}
// NOTE: we cannot use downcast_ref::<String>() here

View File

@ -144,7 +144,7 @@
//! * 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
//! 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.
//! 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.
//!
//! 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
//! access to that data to ensure no *moves* or other invalidation occurs, and finally
//! 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
//! 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
//! will eventaully make up an asynchronous task (including address-sensitive `async fn` state
//! when one considers, for example, the implications of composing together the [`Future`]s which
//! 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,
//! 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.
@ -359,7 +359,7 @@
//! 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
//! 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
//! unsound without being expressed through pinning, and they would then need to not
//! implement [`Unpin`].
@ -953,7 +953,7 @@ use crate::{
/// discussed below.
///
/// 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).
///
/// 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
/// 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
/// [`pin` module] docs, but suffice it to say they require the guarantees provided by pinning to
/// be implemented soundly.

View File

@ -1944,8 +1944,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(slice_split_at_unchecked)]
///
/// let v = [1, 2, 3, 4, 5, 6];
///
/// unsafe {
@ -1966,7 +1964,7 @@ impl<T> [T] {
/// 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")]
#[inline]
#[must_use]
@ -2008,8 +2006,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(slice_split_at_unchecked)]
///
/// let mut v = [1, 0, 3, 0, 5, 6];
/// // scoped to restrict the lifetime of the borrows
/// unsafe {
@ -2021,7 +2017,7 @@ impl<T> [T] {
/// }
/// 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")]
#[inline]
#[must_use]

View File

@ -746,7 +746,13 @@ fn rust_panic_with_hook(
panic_count::MustAbort::PanicInHook => {
// Don't try to print the message in this case
// - 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 => {
// Unfortunately, this does not print a backtrace, because creating

View File

@ -396,7 +396,7 @@ impl<T: ?Sized> Mutex<T> {
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
/// 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()
}
/// 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
/// 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.
// That is overly conservative - the lint should fire even if there was no initializer,
// 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()
{
return false;

View File

@ -6,7 +6,7 @@ use clippy_utils::{is_default_equivalent, path_def_id};
use rustc_errors::Applicability;
use rustc_hir::def::Res;
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_middle::lint::in_external_macro;
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 {
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();
v.visit_ty(ty);
!v.0

View File

@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(
&& let ty::RawPtr(_, to_mutbl) = cast_to.kind()
&& let Some(use_cx) = expr_use_ctxt(cx, expr)
// 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 fn_name = match to_mutbl {

View File

@ -66,7 +66,7 @@ pub(super) fn check<'tcx>(
&& let QPath::Resolved(None, Path { res, .. }) = qpath
&& let Res::Local(hir_id) = res
&& 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
&& 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
} 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
&& 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::{get_enclosing_block, path_to_local_id};
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_session::declare_lint_pass;
use rustc_span::symbol::sym;
@ -58,7 +58,7 @@ static COLLECTIONS: [Symbol; 9] = [
];
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.
if match_acceptable_type(cx, local, &COLLECTIONS)
&& 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);
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

View File

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

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
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 rustc_hir::{Local, LocalSource, PatKind};
use rustc_hir::{LetStmt, LocalSource, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{GenericArgKind, IsSuggestable};
@ -138,7 +138,7 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
];
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)
&& !in_external_macro(cx.tcx.sess, local.span)
&& let PatKind::Wild = local.pat.kind

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet;
use rustc_hir::{Local, TyKind};
use rustc_hir::{LetStmt, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
@ -26,7 +26,7 @@ declare_clippy_lint! {
declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]);
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)
&& let Some(ty) = local.ty // Ensure that it has a type defined
&& 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
&& let PatKind::Binding(bind_ann, ..) = pat.kind
&& !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
{
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_errors::Applicability;
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_middle::hir::nested_filter;
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> {
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
if l.pat.hir_id == self.var_id
&& 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::visitors::any_temporaries_need_ordered_drop;
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;
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) {
([stmt, stmts @ ..], expr) => {
if let StmtKind::Let(&Local {
if let StmtKind::Let(&LetStmt {
init: Some(e),
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_hir::def::Res;
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_middle::hir::nested_filter::OnlyBodies;
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()
}
fn visit_local(&mut self, l: &'tcx Local<'_>) {
fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
if !self.after_loop {
l.pat.each_binding_or_first(&mut |_, 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::{is_trait_method, path_to_local_id};
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_session::impl_lint_pass;
use rustc_span::sym;
@ -60,7 +60,7 @@ impl ManualHashOne {
impl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]);
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();`
if let PatKind::Binding(BindingAnnotation::MUT, hasher, _, None) = local.pat.kind
&& 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
match cx.tcx.parent_hir_node(hir_id) {
Node::Param(..) => (),
Node::Local(local) => {
Node::LetStmt(local) => {
let Some(ty) = local.ty else { return };
if matches!(ty.kind, TyKind::Infer) {
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::{path_to_local_id, peel_blocks, strip_pat_refs};
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 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()
&& let Some(expr) = local.init
&& 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> {
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) {
Node::Local(parent_let_expr) => Some(AssignmentExpr::Local {
Node::LetStmt(parent_let_expr) => Some(AssignmentExpr::Local {
span: parent_let_expr.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_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 rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat};
use rustc_lexer::TokenKind;
use rustc_lint::{LateContext, LateLintPass, LintContext};
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 |=
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 {
match cx.tcx.parent_hir_node(p_expr.hir_id) {
// Compare match_expr ty with local in `let local = match match_expr {..}`
Node::Local(local) => {
Node::LetStmt(local) => {
let results = cx.typeck_results();
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,
},
// 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;
},
_ => false,

View File

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

View File

@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
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_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
&& let ty = cx.typeck_results().expr_ty(collect_expr)
&& [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 {
StmtKind::Expr(expr) | StmtKind::Semi(expr) => Some((expr, None)),
StmtKind::Item(..) => None,
StmtKind::Let(Local { init, pat, .. }) => {
StmtKind::Let(LetStmt { init, pat, .. }) => {
if let PatKind::Binding(_, hir_id, ..) = pat.kind {
init.map(|init_expr| (init_expr, Some(hir_id)))
} 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)
&& is_unwrap_call(cx, unwrap_call_expr)
&& 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((local, _)) = mir
.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 rustc_errors::Applicability;
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_middle::ty;
@ -128,7 +128,7 @@ fn check_manual_split_once_indirect(
) -> Option<()> {
let ctxt = expr.span.ctxt();
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 (iter_stmt_id, Node::Stmt(_)) = parents.next()?
&& let (_, Node::Block(enclosing_block)) = parents.next()?
@ -198,7 +198,7 @@ fn indirect_usage<'tcx>(
binding: HirId,
ctxt: SyntaxContext,
) -> Option<IndirectUsage<'tcx>> {
if let StmtKind::Let(&Local {
if let StmtKind::Let(&LetStmt {
pat: Pat {
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:
// - 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()
{
return false;

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
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_middle::ty;
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<'_>) {
match stmt.kind {
StmtKind::Let(local) => {
if let Local { init: Some(e), .. } = local {
if let LetStmt { init: Some(e), .. } = local {
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 {
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 rustc_errors::{Applicability, MultiSpan};
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,
};
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 <pat>: <ty>;
// ~~~~~~~~~~~~~~~
@ -252,7 +252,7 @@ fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &Local<'_>) -> O
fn check<'tcx>(
cx: &LateContext<'tcx>,
local: &'tcx Local<'tcx>,
local: &'tcx LetStmt<'tcx>,
local_stmt: &'tcx Stmt<'tcx>,
block: &'tcx Block<'tcx>,
binding_id: HirId,
@ -363,9 +363,9 @@ fn check<'tcx>(
}
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);
if let Local {
if let LetStmt {
init: None,
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) {
Some((Node::Stmt(_), _)) => (),
Some((Node::Local(l), _)) => {
Some((Node::LetStmt(l), _)) => {
// Only trace simple bindings. e.g `let x = y;`
if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind {
self.bindings.insert(id, args_idx);

View File

@ -14,7 +14,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
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_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<'_>) {
if let StmtKind::Let(Local {
if let StmtKind::Let(LetStmt {
pat,
init: Some(init_expr),
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::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_hir as hir;
use rustc_hir::def::Res;
@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
}
if let StmtKind::Let(local) = stmt.kind
&& let Local {
&& let LetStmt {
pat, init: Some(init), ..
} = local
&& 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 rustc_ast::Mutability;
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_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
@ -47,7 +47,7 @@ declare_clippy_lint! {
declare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]);
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)
// the pattern is a single by-value binding
&& 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 {
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)
// type annotation part
&& !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 rustc_errors::Applicability;
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_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
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
&& let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind
&& !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),
_ => None,
},
Node::Local(local) => local.init,
Node::LetStmt(local) => local.init,
_ => None,
};
return init;

View File

@ -159,7 +159,7 @@ fn all_bindings_are_for_conv<'tcx>(
.iter()
.map(|node| match node {
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,
})
.all_equal()
@ -170,7 +170,7 @@ fn all_bindings_are_for_conv<'tcx>(
&& local_parents.first().is_some_and(|node| {
let Some(ty) = match node {
Node::Pat(pat) => Some(pat.hir_id),
Node::Local(l) => Some(l.hir_id),
Node::LetStmt(l) => Some(l.hir_id),
_ => None,
}
.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::intravisit::FnKind;
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,
};
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 {
self.check_ty(
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>) {
let (hir::StmtKind::Let(&hir::Local { init: Some(expr), .. })
let (hir::StmtKind::Let(&hir::LetStmt { init: Some(expr), .. })
| hir::StmtKind::Expr(expr)
| hir::StmtKind::Semi(expr)) = stmt.kind
else {
@ -342,7 +342,7 @@ fn block_parents_have_safety_comment(
) -> bool {
let (span, hir_id) = match cx.tcx.parent_hir_node(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 {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
span,
@ -358,12 +358,12 @@ fn block_parents_have_safety_comment(
},
Node::Stmt(hir::Stmt {
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::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 {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
span,
@ -603,7 +603,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
for (_, node) in map.parent_iter(body.hir_id) {
match node {
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 {
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 rustc_errors::Applicability;
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_middle::lint::{in_external_macro, is_from_async_await};
use rustc_middle::ty;
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 () = { ... }`
if let PatKind::Tuple(fields, ..) = local.pat.kind
&& fields.is_empty()
@ -102,7 +102,7 @@ fn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -
return false;
}
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)) {
return false;
}

View File

@ -3,7 +3,7 @@ mod unit_arg;
mod unit_cmp;
mod utils;
use rustc_hir::{Expr, Local};
use rustc_hir::{Expr, LetStmt};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
@ -99,7 +99,7 @@ declare_clippy_lint! {
declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
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);
}

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 rustc_ast::Mutability;
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_middle::hir::nested_filter::OnlyBodies;
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) {
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>> {
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),
_ => 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 {
ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.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)
} else {
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::{get_parent_expr, higher, is_trait_method};
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_middle::ty;
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) {
// 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)
Node::Local(Local {
Node::LetStmt(LetStmt {
ty: None,
pat:
Pat {
@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
}
},
// 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);
},
// search for `for _ in vec![...]`

View File

@ -7,7 +7,7 @@ use core::ops::ControlFlow;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
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_middle::lint::in_external_macro;
@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
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
&& let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind
&& !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 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(
cx,
l.span,

View File

@ -99,7 +99,7 @@ use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::{
self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr,
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,
};
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>> {
if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
&& 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;
}
@ -1079,7 +1079,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
},
_ => break,
},
Node::Local(l) => match pat_capture_kind(cx, l.pat) {
Node::LetStmt(l) => match pat_capture_kind(cx, l.pat) {
CaptureKind::Value => break,
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),
_ => (),
},
Node::Stmt(_) | Node::Block(_) | Node::Local(_) | Node::Arm(_) => (),
Node::Stmt(_) | Node::Block(_) | Node::LetStmt(_) | Node::Arm(_) => (),
_ => 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 {
let mut child_id = expr.hir_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),
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 {
let mut child_id = expr.hir_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
{
return true;
@ -2158,7 +2158,7 @@ pub fn is_expr_used_or_unified(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
Node::Stmt(Stmt {
kind: StmtKind::Expr(_)
| StmtKind::Semi(_)
| StmtKind::Let(Local {
| StmtKind::Let(LetStmt {
pat: Pat {
kind: PatKind::Wild,
..
@ -2639,7 +2639,7 @@ pub struct ExprUseCtxt<'tcx> {
/// The node which consumes a value.
pub enum ExprUseNode<'tcx> {
/// Assignment to, or initializer for, a local
Local(&'tcx Local<'tcx>),
LetStmt(&'tcx LetStmt<'tcx>),
/// Initializer for a const or static item.
ConstStatic(OwnerId),
/// 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.
pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> {
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(
cx.param_env
.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();
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()
.map(|(use_node, child_id)| {
let node = match use_node {
Node::Local(l) => ExprUseNode::Local(l),
Node::LetStmt(l) => ExprUseNode::LetStmt(l),
Node::ExprField(field) => ExprUseNode::Field(field),
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 {
self.visit_expr(e);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,7 @@
#![crate_type = "lib"]
// 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 -Cdebug-assertions=no
//@ compile-flags: -Zmir-opt-level=2 -Zinline-mir
// EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff
// 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