mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-26 04:17:21 +00:00
Auto merge of #8942 - flip1995:rustup, r=flip1995
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
d9ddce8a22
25 changed files with 123 additions and 80 deletions
|
@ -12,12 +12,12 @@ use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
|
||||||
|
|
||||||
use super::UNNECESSARY_CAST;
|
use super::UNNECESSARY_CAST;
|
||||||
|
|
||||||
pub(super) fn check(
|
pub(super) fn check<'tcx>(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'tcx>,
|
||||||
expr: &Expr<'_>,
|
expr: &Expr<'tcx>,
|
||||||
cast_expr: &Expr<'_>,
|
cast_expr: &Expr<'tcx>,
|
||||||
cast_from: Ty<'_>,
|
cast_from: Ty<'tcx>,
|
||||||
cast_to: Ty<'_>,
|
cast_to: Ty<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// skip non-primitive type cast
|
// skip non-primitive type cast
|
||||||
if_chain! {
|
if_chain! {
|
||||||
|
|
|
@ -90,7 +90,7 @@ fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> {
|
||||||
while let Some(curr) = cursor.next() {
|
while let Some(curr) = cursor.next() {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if !prev_is_dollar;
|
if !prev_is_dollar;
|
||||||
if let Some(span) = is_crate_keyword(&curr);
|
if let Some(span) = is_crate_keyword(curr);
|
||||||
if let Some(next) = cursor.look_ahead(0);
|
if let Some(next) = cursor.look_ahead(0);
|
||||||
if is_token(next, &TokenKind::ModSep);
|
if is_token(next, &TokenKind::ModSep);
|
||||||
then {
|
then {
|
||||||
|
@ -103,7 +103,7 @@ fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> {
|
||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev_is_dollar = is_token(&curr, &TokenKind::Dollar);
|
prev_is_dollar = is_token(curr, &TokenKind::Dollar);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,7 +446,7 @@ fn try_parse_ref_op<'tcx>(
|
||||||
|
|
||||||
// Checks whether the type for a deref call actually changed the type, not just the mutability of
|
// Checks whether the type for a deref call actually changed the type, not just the mutability of
|
||||||
// the reference.
|
// the reference.
|
||||||
fn deref_method_same_type(result_ty: Ty<'_>, arg_ty: Ty<'_>) -> bool {
|
fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
|
||||||
match (result_ty.kind(), arg_ty.kind()) {
|
match (result_ty.kind(), arg_ty.kind()) {
|
||||||
(ty::Ref(_, result_ty, _), ty::Ref(_, arg_ty, _)) => result_ty == arg_ty,
|
(ty::Ref(_, result_ty, _), ty::Ref(_, arg_ty, _)) => result_ty == arg_ty,
|
||||||
|
|
||||||
|
@ -541,8 +541,8 @@ fn is_auto_borrow_position(parent: Option<Node<'_>>, child_id: HirId) -> bool {
|
||||||
/// Adjustments are sometimes made in the parent block rather than the expression itself.
|
/// Adjustments are sometimes made in the parent block rather than the expression itself.
|
||||||
fn find_adjustments<'tcx>(
|
fn find_adjustments<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
typeck: &'tcx TypeckResults<'_>,
|
typeck: &'tcx TypeckResults<'tcx>,
|
||||||
expr: &'tcx Expr<'_>,
|
expr: &'tcx Expr<'tcx>,
|
||||||
) -> &'tcx [Adjustment<'tcx>] {
|
) -> &'tcx [Adjustment<'tcx>] {
|
||||||
let map = tcx.hir();
|
let map = tcx.hir();
|
||||||
let mut iter = map.parent_iter(expr.hir_id);
|
let mut iter = map.parent_iter(expr.hir_id);
|
||||||
|
@ -581,7 +581,7 @@ fn find_adjustments<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::needless_pass_by_value)]
|
#[expect(clippy::needless_pass_by_value)]
|
||||||
fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData) {
|
fn report<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, state: State, data: StateData) {
|
||||||
match state {
|
match state {
|
||||||
State::DerefMethod {
|
State::DerefMethod {
|
||||||
ty_changed_count,
|
ty_changed_count,
|
||||||
|
@ -656,7 +656,7 @@ fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dereferencing {
|
impl Dereferencing {
|
||||||
fn check_local_usage(&mut self, cx: &LateContext<'_>, e: &Expr<'_>, local: HirId) {
|
fn check_local_usage<'tcx>(&mut self, cx: &LateContext<'tcx>, e: &Expr<'tcx>, local: HirId) {
|
||||||
if let Some(outer_pat) = self.ref_locals.get_mut(&local) {
|
if let Some(outer_pat) = self.ref_locals.get_mut(&local) {
|
||||||
if let Some(pat) = outer_pat {
|
if let Some(pat) = outer_pat {
|
||||||
// Check for auto-deref
|
// Check for auto-deref
|
||||||
|
|
|
@ -189,7 +189,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
|
fn fake_read(&mut self, _: &rustc_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
|
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
|
||||||
|
|
|
@ -4,7 +4,8 @@ use clippy_utils::source::snippet_with_applicability;
|
||||||
use clippy_utils::{is_expn_of, match_function_call, paths};
|
use clippy_utils::{is_expn_of, match_function_call, paths};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::def::Res;
|
||||||
|
use rustc_hir::{BindingAnnotation, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
@ -47,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
|
||||||
if let ExprKind::MethodCall(unwrap_fun, [write_call], _) = expr.kind;
|
if let ExprKind::MethodCall(unwrap_fun, [write_call], _) = expr.kind;
|
||||||
if unwrap_fun.ident.name == sym::unwrap;
|
if unwrap_fun.ident.name == sym::unwrap;
|
||||||
// match call to write_fmt
|
// match call to write_fmt
|
||||||
if let ExprKind::MethodCall(write_fun, [write_recv, write_arg], _) = write_call.kind;
|
if let ExprKind::MethodCall(write_fun, [write_recv, write_arg], _) = look_in_block(cx, &write_call.kind);
|
||||||
if write_fun.ident.name == sym!(write_fmt);
|
if write_fun.ident.name == sym!(write_fmt);
|
||||||
// match calls to std::io::stdout() / std::io::stderr ()
|
// match calls to std::io::stdout() / std::io::stderr ()
|
||||||
if let Some(dest_name) = if match_function_call(cx, write_recv, &paths::STDOUT).is_some() {
|
if let Some(dest_name) = if match_function_call(cx, write_recv, &paths::STDOUT).is_some() {
|
||||||
|
@ -108,3 +109,34 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If `kind` is a block that looks like `{ let result = $expr; result }` then
|
||||||
|
/// returns $expr. Otherwise returns `kind`.
|
||||||
|
fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>) -> &'tcx ExprKind<'hir> {
|
||||||
|
if_chain! {
|
||||||
|
if let ExprKind::Block(block, _label @ None) = kind;
|
||||||
|
if let Block {
|
||||||
|
stmts: [Stmt { kind: StmtKind::Local(local), .. }],
|
||||||
|
expr: Some(expr_end_of_block),
|
||||||
|
rules: BlockCheckMode::DefaultBlock,
|
||||||
|
..
|
||||||
|
} = block;
|
||||||
|
|
||||||
|
// Find id of the local that expr_end_of_block resolves to
|
||||||
|
if let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind;
|
||||||
|
if let Res::Local(expr_res) = expr_path.res;
|
||||||
|
if let Some(Node::Binding(res_pat)) = cx.tcx.hir().find(expr_res);
|
||||||
|
|
||||||
|
// Find id of the local we found in the block
|
||||||
|
if let PatKind::Binding(BindingAnnotation::Unannotated, local_hir_id, _ident, None) = local.pat.kind;
|
||||||
|
|
||||||
|
// If those two are the same hir id
|
||||||
|
if res_pat.hir_id == local_hir_id;
|
||||||
|
|
||||||
|
if let Some(init) = local.init;
|
||||||
|
then {
|
||||||
|
return &init.kind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kind
|
||||||
|
}
|
||||||
|
|
|
@ -259,8 +259,8 @@ fn parse_len_output<'tcx>(cx: &LateContext<'_>, sig: FnSig<'tcx>) -> Option<LenO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LenOutput<'_> {
|
impl<'tcx> LenOutput<'tcx> {
|
||||||
fn matches_is_empty_output(self, ty: Ty<'_>) -> bool {
|
fn matches_is_empty_output(self, ty: Ty<'tcx>) -> bool {
|
||||||
match (self, ty.kind()) {
|
match (self, ty.kind()) {
|
||||||
(_, &ty::Bool) => true,
|
(_, &ty::Bool) => true,
|
||||||
(Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(),
|
(Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(),
|
||||||
|
@ -292,7 +292,7 @@ impl LenOutput<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the given signature matches the expectations for `is_empty`
|
/// Checks if the given signature matches the expectations for `is_empty`
|
||||||
fn check_is_empty_sig(sig: FnSig<'_>, self_kind: ImplicitSelfKind, len_output: LenOutput<'_>) -> bool {
|
fn check_is_empty_sig<'tcx>(sig: FnSig<'tcx>, self_kind: ImplicitSelfKind, len_output: LenOutput<'tcx>) -> bool {
|
||||||
match &**sig.inputs_and_output {
|
match &**sig.inputs_and_output {
|
||||||
[arg, res] if len_output.matches_is_empty_output(*res) => {
|
[arg, res] if len_output.matches_is_empty_output(*res) => {
|
||||||
matches!(
|
matches!(
|
||||||
|
@ -306,11 +306,11 @@ fn check_is_empty_sig(sig: FnSig<'_>, self_kind: ImplicitSelfKind, len_output: L
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the given type has an `is_empty` method with the appropriate signature.
|
/// Checks if the given type has an `is_empty` method with the appropriate signature.
|
||||||
fn check_for_is_empty(
|
fn check_for_is_empty<'tcx>(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
self_kind: ImplicitSelfKind,
|
self_kind: ImplicitSelfKind,
|
||||||
output: LenOutput<'_>,
|
output: LenOutput<'tcx>,
|
||||||
impl_ty: DefId,
|
impl_ty: DefId,
|
||||||
item_name: Symbol,
|
item_name: Symbol,
|
||||||
item_kind: &str,
|
item_kind: &str,
|
||||||
|
|
|
@ -371,7 +371,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
|
||||||
if let Some(ref lt) = *lifetime {
|
if let Some(ref lt) = *lifetime {
|
||||||
if lt.name == LifetimeName::Static {
|
if lt.name == LifetimeName::Static {
|
||||||
self.lts.push(RefLt::Static);
|
self.lts.push(RefLt::Static);
|
||||||
} else if let LifetimeName::Param(ParamName::Fresh(_)) = lt.name {
|
} else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name {
|
||||||
// Fresh lifetimes generated should be ignored.
|
// Fresh lifetimes generated should be ignored.
|
||||||
} else if lt.is_elided() {
|
} else if lt.is_elided() {
|
||||||
self.lts.push(RefLt::Unnamed);
|
self.lts.push(RefLt::Unnamed);
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
|
fn fake_read(&mut self, _: &rustc_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MutatePairDelegate<'_, '_> {
|
impl MutatePairDelegate<'_, '_> {
|
||||||
|
|
|
@ -117,7 +117,9 @@ pub(super) fn check<'tcx>(
|
||||||
let take_expr = sugg::Sugg::hir(cx, take_expr, "<count>");
|
let take_expr = sugg::Sugg::hir(cx, take_expr, "<count>");
|
||||||
format!(".take({})", take_expr + sugg::ONE)
|
format!(".take({})", take_expr + sugg::ONE)
|
||||||
},
|
},
|
||||||
ast::RangeLimits::HalfOpen => format!(".take({})", snippet(cx, take_expr.span, "..")),
|
ast::RangeLimits::HalfOpen => {
|
||||||
|
format!(".take({})", snippet(cx, take_expr.span, ".."))
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -262,7 +264,11 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
|
||||||
match res {
|
match res {
|
||||||
Res::Local(hir_id) => {
|
Res::Local(hir_id) => {
|
||||||
let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
|
let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
|
||||||
let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id).unwrap();
|
let extent = self.cx
|
||||||
|
.tcx
|
||||||
|
.region_scope_tree(parent_def_id)
|
||||||
|
.var_scope(hir_id.local_id)
|
||||||
|
.unwrap();
|
||||||
if index_used_directly {
|
if index_used_directly {
|
||||||
self.indexed_directly.insert(
|
self.indexed_directly.insert(
|
||||||
seqvar.segments[0].ident.name,
|
seqvar.segments[0].ident.name,
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
|
||||||
let mut iter = fields.iter().filter_map(|f| match f.vis.kind {
|
let mut iter = fields.iter().filter_map(|f| match f.vis.kind {
|
||||||
VisibilityKind::Public => None,
|
VisibilityKind::Public => None,
|
||||||
VisibilityKind::Inherited => Some(Ok(f)),
|
VisibilityKind::Inherited => Some(Ok(f)),
|
||||||
_ => Some(Err(())),
|
VisibilityKind::Restricted { .. } => Some(Err(())),
|
||||||
});
|
});
|
||||||
if let Some(Ok(field)) = iter.next()
|
if let Some(Ok(field)) = iter.next()
|
||||||
&& iter.next().is_none()
|
&& iter.next().is_none()
|
||||||
|
|
|
@ -2882,7 +2882,7 @@ enum SelfKind {
|
||||||
|
|
||||||
impl SelfKind {
|
impl SelfKind {
|
||||||
fn matches<'a>(self, cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
|
fn matches<'a>(self, cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
|
||||||
fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'_>, ty: Ty<'_>) -> bool {
|
fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
|
||||||
if ty == parent_ty {
|
if ty == parent_ty {
|
||||||
true
|
true
|
||||||
} else if ty.is_box() {
|
} else if ty.is_box() {
|
||||||
|
|
|
@ -343,5 +343,5 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
|
||||||
|
|
||||||
fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}
|
fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}
|
||||||
|
|
||||||
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
|
fn fake_read(&mut self, _: &rustc_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,7 +343,7 @@ impl fmt::Display for RefPrefix {
|
||||||
use fmt::Write;
|
use fmt::Write;
|
||||||
f.write_char('&')?;
|
f.write_char('&')?;
|
||||||
match self.lt {
|
match self.lt {
|
||||||
LifetimeName::Param(ParamName::Plain(name)) => {
|
LifetimeName::Param(_, ParamName::Plain(name)) => {
|
||||||
name.fmt(f)?;
|
name.fmt(f)?;
|
||||||
f.write_char(' ')?;
|
f.write_char(' ')?;
|
||||||
},
|
},
|
||||||
|
@ -395,9 +395,9 @@ impl<'tcx> DerefTy<'tcx> {
|
||||||
|
|
||||||
fn check_fn_args<'cx, 'tcx: 'cx>(
|
fn check_fn_args<'cx, 'tcx: 'cx>(
|
||||||
cx: &'cx LateContext<'tcx>,
|
cx: &'cx LateContext<'tcx>,
|
||||||
tys: &'tcx [Ty<'_>],
|
tys: &'tcx [Ty<'tcx>],
|
||||||
hir_tys: &'tcx [hir::Ty<'_>],
|
hir_tys: &'tcx [hir::Ty<'tcx>],
|
||||||
params: &'tcx [Param<'_>],
|
params: &'tcx [Param<'tcx>],
|
||||||
) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {
|
) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {
|
||||||
tys.iter()
|
tys.iter()
|
||||||
.zip(hir_tys.iter())
|
.zip(hir_tys.iter())
|
||||||
|
|
|
@ -292,7 +292,7 @@ fn is_call_with_ref_arg<'tcx>(
|
||||||
if let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(mir, cx.tcx));
|
if let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(mir, cx.tcx));
|
||||||
if !is_copy(cx, inner_ty);
|
if !is_copy(cx, inner_ty);
|
||||||
then {
|
then {
|
||||||
Some((def_id, *local, inner_ty, destination.as_ref().map(|(dest, _)| dest)?.as_local()?))
|
Some((def_id, *local, inner_ty, destination.as_local()?))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
|
||||||
fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Location) {
|
fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Location) {
|
||||||
if let mir::TerminatorKind::Call {
|
if let mir::TerminatorKind::Call {
|
||||||
args,
|
args,
|
||||||
destination: Some((mir::Place { local: dest, .. }, _)),
|
destination: mir::Place { local: dest, .. },
|
||||||
..
|
..
|
||||||
} = &terminator.kind
|
} = &terminator.kind
|
||||||
{
|
{
|
||||||
|
|
|
@ -358,7 +358,7 @@ fn is_size_pair(ty: Ty<'_>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn same_except_params(subs1: SubstsRef<'_>, subs2: SubstsRef<'_>) -> bool {
|
fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> bool {
|
||||||
// TODO: check const parameters as well. Currently this will consider `Array<5>` the same as
|
// TODO: check const parameters as well. Currently this will consider `Array<5>` the same as
|
||||||
// `Array<6>`
|
// `Array<6>`
|
||||||
for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {
|
for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {
|
||||||
|
|
|
@ -187,11 +187,13 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> bool {
|
||||||
&& Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
|
&& Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
|
||||||
&& let Some(src) = unsafe_line.sf.src.as_deref()
|
&& let Some(src) = unsafe_line.sf.src.as_deref()
|
||||||
{
|
{
|
||||||
|
unsafe_line.sf.lines(|lines| {
|
||||||
comment_start_line.line < unsafe_line.line && text_has_safety_comment(
|
comment_start_line.line < unsafe_line.line && text_has_safety_comment(
|
||||||
src,
|
src,
|
||||||
&unsafe_line.sf.lines[comment_start_line.line + 1..=unsafe_line.line],
|
&lines[comment_start_line.line + 1..=unsafe_line.line],
|
||||||
unsafe_line.sf.start_pos.to_usize(),
|
unsafe_line.sf.start_pos.to_usize(),
|
||||||
)
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// Problem getting source text. Pretend a comment was found.
|
// Problem getting source text. Pretend a comment was found.
|
||||||
true
|
true
|
||||||
|
@ -249,11 +251,13 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
|
||||||
&& Lrc::ptr_eq(&unsafe_line.sf, ¯o_line.sf)
|
&& Lrc::ptr_eq(&unsafe_line.sf, ¯o_line.sf)
|
||||||
&& let Some(src) = unsafe_line.sf.src.as_deref()
|
&& let Some(src) = unsafe_line.sf.src.as_deref()
|
||||||
{
|
{
|
||||||
|
unsafe_line.sf.lines(|lines| {
|
||||||
macro_line.line < unsafe_line.line && text_has_safety_comment(
|
macro_line.line < unsafe_line.line && text_has_safety_comment(
|
||||||
src,
|
src,
|
||||||
&unsafe_line.sf.lines[macro_line.line + 1..=unsafe_line.line],
|
&lines[macro_line.line + 1..=unsafe_line.line],
|
||||||
unsafe_line.sf.start_pos.to_usize(),
|
unsafe_line.sf.start_pos.to_usize(),
|
||||||
)
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// Problem getting source text. Pretend a comment was found.
|
// Problem getting source text. Pretend a comment was found.
|
||||||
true
|
true
|
||||||
|
@ -276,11 +280,13 @@ fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
|
||||||
// Get the text from the start of function body to the unsafe block.
|
// Get the text from the start of function body to the unsafe block.
|
||||||
// fn foo() { some_stuff; unsafe { stuff }; other_stuff; }
|
// fn foo() { some_stuff; unsafe { stuff }; other_stuff; }
|
||||||
// ^-------------^
|
// ^-------------^
|
||||||
|
unsafe_line.sf.lines(|lines| {
|
||||||
body_line.line < unsafe_line.line && text_has_safety_comment(
|
body_line.line < unsafe_line.line && text_has_safety_comment(
|
||||||
src,
|
src,
|
||||||
&unsafe_line.sf.lines[body_line.line + 1..=unsafe_line.line],
|
&lines[body_line.line + 1..=unsafe_line.line],
|
||||||
unsafe_line.sf.start_pos.to_usize(),
|
unsafe_line.sf.start_pos.to_usize(),
|
||||||
)
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// Problem getting source text. Pretend a comment was found.
|
// Problem getting source text. Pretend a comment was found.
|
||||||
true
|
true
|
||||||
|
|
|
@ -545,7 +545,7 @@ pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {
|
||||||
pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {
|
pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {
|
||||||
use VisibilityKind::*;
|
use VisibilityKind::*;
|
||||||
match (&l.kind, &r.kind) {
|
match (&l.kind, &r.kind) {
|
||||||
(Public, Public) | (Inherited, Inherited) | (Crate(_), Crate(_)) => true,
|
(Public, Public) | (Inherited, Inherited) => true,
|
||||||
(Restricted { path: l, .. }, Restricted { path: r, .. }) => eq_path(l, r),
|
(Restricted { path: l, .. }, Restricted { path: r, .. }) => eq_path(l, r),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,8 +274,11 @@ pub fn span_lint_and_sugg_for_edges(
|
||||||
let sm = cx.sess().source_map();
|
let sm = cx.sess().source_map();
|
||||||
if let (Ok(line_upper), Ok(line_bottom)) = (sm.lookup_line(sp.lo()), sm.lookup_line(sp.hi())) {
|
if let (Ok(line_upper), Ok(line_bottom)) = (sm.lookup_line(sp.lo()), sm.lookup_line(sp.hi())) {
|
||||||
let split_idx = MAX_SUGGESTION_HIGHLIGHT_LINES / 2;
|
let split_idx = MAX_SUGGESTION_HIGHLIGHT_LINES / 2;
|
||||||
let span_upper = sm.span_until_char(sp.with_hi(line_upper.sf.lines[line_upper.line + split_idx]), '\n');
|
let span_upper = sm.span_until_char(
|
||||||
let span_bottom = sp.with_lo(line_bottom.sf.lines[line_bottom.line - split_idx]);
|
sp.with_hi(line_upper.sf.lines(|lines| lines[line_upper.line + split_idx])),
|
||||||
|
'\n',
|
||||||
|
);
|
||||||
|
let span_bottom = sp.with_lo(line_bottom.sf.lines(|lines| lines[line_bottom.line - split_idx]));
|
||||||
|
|
||||||
let sugg_lines_vec = sugg.lines().collect::<Vec<&str>>();
|
let sugg_lines_vec = sugg.lines().collect::<Vec<&str>>();
|
||||||
let sugg_upper = sugg_lines_vec[..split_idx].join("\n");
|
let sugg_upper = sugg_lines_vec[..split_idx].join("\n");
|
||||||
|
|
|
@ -902,16 +902,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
|
|
||||||
pub fn hash_lifetime(&mut self, lifetime: Lifetime) {
|
pub fn hash_lifetime(&mut self, lifetime: Lifetime) {
|
||||||
std::mem::discriminant(&lifetime.name).hash(&mut self.s);
|
std::mem::discriminant(&lifetime.name).hash(&mut self.s);
|
||||||
if let LifetimeName::Param(ref name) = lifetime.name {
|
if let LifetimeName::Param(param_id, ref name) = lifetime.name {
|
||||||
std::mem::discriminant(name).hash(&mut self.s);
|
std::mem::discriminant(name).hash(&mut self.s);
|
||||||
|
param_id.hash(&mut self.s);
|
||||||
match name {
|
match name {
|
||||||
ParamName::Plain(ref ident) => {
|
ParamName::Plain(ref ident) => {
|
||||||
ident.name.hash(&mut self.s);
|
ident.name.hash(&mut self.s);
|
||||||
},
|
},
|
||||||
ParamName::Fresh(ref size) => {
|
ParamName::Fresh | ParamName::Error => {},
|
||||||
size.hash(&mut self.s);
|
|
||||||
},
|
|
||||||
ParamName::Error => {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1149,7 +1149,7 @@ fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
|
||||||
let span = original_sp(span, DUMMY_SP);
|
let span = original_sp(span, DUMMY_SP);
|
||||||
let source_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
|
let source_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
|
||||||
let line_no = source_map_and_line.line;
|
let line_no = source_map_and_line.line;
|
||||||
let line_start = source_map_and_line.sf.lines[line_no];
|
let line_start = source_map_and_line.sf.lines(|lines| lines[line_no]);
|
||||||
span.with_lo(line_start)
|
span.with_lo(line_start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,24 +121,18 @@ fn check_rvalue<'tcx>(
|
||||||
) -> McfResult {
|
) -> McfResult {
|
||||||
match rvalue {
|
match rvalue {
|
||||||
Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
|
Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
|
||||||
Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => check_operand(tcx, operand, span, body),
|
|
||||||
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
|
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
|
||||||
check_place(tcx, *place, span, body)
|
check_place(tcx, *place, span, body)
|
||||||
},
|
},
|
||||||
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
|
Rvalue::Repeat(operand, _)
|
||||||
use rustc_middle::ty::cast::CastTy;
|
| Rvalue::Use(operand)
|
||||||
let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
|
| Rvalue::Cast(
|
||||||
let cast_out = CastTy::from_ty(*cast_ty).expect("bad output type for cast");
|
CastKind::PointerFromExposedAddress
|
||||||
match (cast_in, cast_out) {
|
| CastKind::Misc
|
||||||
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
|
| CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
|
||||||
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
operand,
|
||||||
},
|
_,
|
||||||
_ => check_operand(tcx, operand, span, body),
|
) => check_operand(tcx, operand, span, body),
|
||||||
}
|
|
||||||
},
|
|
||||||
Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), operand, _) => {
|
|
||||||
check_operand(tcx, operand, span, body)
|
|
||||||
},
|
|
||||||
Rvalue::Cast(
|
Rvalue::Cast(
|
||||||
CastKind::Pointer(
|
CastKind::Pointer(
|
||||||
PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
|
PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
|
||||||
|
@ -163,6 +157,9 @@ fn check_rvalue<'tcx>(
|
||||||
Err((span, "unsizing casts are not allowed in const fn".into()))
|
Err((span, "unsizing casts are not allowed in const fn".into()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
|
||||||
|
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
||||||
|
},
|
||||||
// binops are fine on integers
|
// binops are fine on integers
|
||||||
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
|
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
|
||||||
check_operand(tcx, lhs, span, body)?;
|
check_operand(tcx, lhs, span, body)?;
|
||||||
|
@ -301,6 +298,7 @@ fn check_terminator<'a, 'tcx>(
|
||||||
args,
|
args,
|
||||||
from_hir_call: _,
|
from_hir_call: _,
|
||||||
destination: _,
|
destination: _,
|
||||||
|
target: _,
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
fn_span: _,
|
fn_span: _,
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
|
||||||
|
|
||||||
fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
|
fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
|
||||||
|
|
||||||
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
|
fn fake_read(&mut self, _: &rustc_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walks into `ty` and returns `true` if any inner type is the same as `other_ty`
|
/// Walks into `ty` and returns `true` if any inner type is the same as `other_ty`
|
||||||
pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool {
|
pub fn contains_ty<'tcx>(ty: Ty<'tcx>, other_ty: Ty<'tcx>) -> bool {
|
||||||
ty.walk().any(|inner| match inner.unpack() {
|
ty.walk().any(|inner| match inner.unpack() {
|
||||||
GenericArgKind::Type(inner_ty) => other_ty == inner_ty,
|
GenericArgKind::Type(inner_ty) => other_ty == inner_ty,
|
||||||
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
||||||
|
@ -52,7 +52,7 @@ pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool {
|
||||||
|
|
||||||
/// Walks into `ty` and returns `true` if any inner type is an instance of the given adt
|
/// Walks into `ty` and returns `true` if any inner type is an instance of the given adt
|
||||||
/// constructor.
|
/// constructor.
|
||||||
pub fn contains_adt_constructor(ty: Ty<'_>, adt: AdtDef<'_>) -> bool {
|
pub fn contains_adt_constructor<'tcx>(ty: Ty<'tcx>, adt: AdtDef<'tcx>) -> bool {
|
||||||
ty.walk().any(|inner| match inner.unpack() {
|
ty.walk().any(|inner| match inner.unpack() {
|
||||||
GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt),
|
GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt),
|
||||||
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
|
||||||
self.update(cmt);
|
self.update(cmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
|
fn fake_read(&mut self, _: &rustc_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ParamBindingIdCollector {
|
pub struct ParamBindingIdCollector {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2022-05-19"
|
channel = "nightly-2022-06-04"
|
||||||
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||||
|
|
Loading…
Add table
Reference in a new issue