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:
commit
020bbe46bd
113 changed files with 567 additions and 280 deletions
9
.github/workflows/dependencies.yml
vendored
9
.github/workflows/dependencies.yml
vendored
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
})
|
})
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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`"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(":");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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, |_| {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(_),
|
||||||
..
|
..
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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),
|
||||||
..
|
..
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>);
|
||||||
|
|
|
@ -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 = ();`
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 '_'
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
..
|
..
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
..
|
..
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(..),
|
||||||
..
|
..
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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![...]`
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue