Merge pull request #13639 from flip1995/rustup

Rustup
This commit is contained in:
Philipp Krones 2024-11-07 18:02:25 +00:00 committed by GitHub
commit 3518178443
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
83 changed files with 531 additions and 507 deletions

View File

@ -1,6 +1,5 @@
# Clippy
[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test%20(bors)/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test+(bors)%22+event%3Apush+branch%3Aauto)
[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](#license)
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.

View File

@ -1,6 +1,5 @@
# Clippy
[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test%20(bors)/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test+(bors)%22+event%3Apush+branch%3Aauto)
[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](https://github.com/rust-lang/rust-clippy#license)
A collection of lints to catch common mistakes and improve your

View File

@ -762,13 +762,19 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
Literal{..}(desc)
);
if let Some(LintDeclSearchResult {
token_kind: TokenKind::CloseBrace,
range,
..
}) = iter.next()
{
lints.push(Lint::new(name, group, desc, module, start..range.end));
if let Some(end) = iter.find_map(|t| {
if let LintDeclSearchResult {
token_kind: TokenKind::CloseBrace,
range,
..
} = t
{
Some(range.end)
} else {
None
}
}) {
lints.push(Lint::new(name, group, desc, module, start..end));
}
}
}

View File

@ -3,11 +3,11 @@
use clippy_utils::is_from_proc_macro;
use rustc_ast::{AttrStyle, Attribute};
use rustc_errors::Applicability;
use rustc_lint::{LateContext, LintContext};
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
// Separate each crate's features.
pub fn check<'cx>(cx: &LateContext<'cx>, attr: &'cx Attribute) {
pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {
if !in_external_macro(cx.sess(), attr.span)
&& let AttrStyle::Outer = attr.style
&& let Some(ident) = attr.ident()

View File

@ -2,12 +2,12 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use rustc_ast::{MetaItemInner, MetaItemKind};
use rustc_lint::{LateContext, LintContext};
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::sym;
use rustc_span::symbol::Symbol;
pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[MetaItemInner], attr: &'cx Attribute) {
pub(super) fn check<'cx>(cx: &EarlyContext<'cx>, name: Symbol, items: &[MetaItemInner], attr: &'cx Attribute) {
// Check if the reason is present
if let Some(item) = items.last().and_then(MetaItemInner::meta_item)
&& let MetaItemKind::NameValue(_) = &item.kind

View File

@ -2,11 +2,11 @@
use super::utils::extract_clippy_lint;
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
use rustc_ast::MetaItemInner;
use rustc_lint::{LateContext, Level, LintContext};
use rustc_lint::{EarlyContext, Level, LintContext};
use rustc_span::symbol::Symbol;
use rustc_span::{DUMMY_SP, sym};
pub(super) fn check(cx: &LateContext<'_>, name: Symbol, items: &[MetaItemInner]) {
pub(super) fn check(cx: &EarlyContext<'_>, name: Symbol, items: &[MetaItemInner]) {
for lint in items {
if let Some(lint_name) = extract_clippy_lint(lint) {
if lint_name.as_str() == "restriction" && name != sym::allow {
@ -23,7 +23,7 @@ pub(super) fn check(cx: &LateContext<'_>, name: Symbol, items: &[MetaItemInner])
}
}
pub(super) fn check_command_line(cx: &LateContext<'_>) {
pub(super) fn check_command_line(cx: &EarlyContext<'_>) {
for (name, level) in &cx.sess().opts.lint_opts {
if name == "clippy::restriction" && *level > Level::Allow {
span_lint_and_then(

View File

@ -1,11 +1,11 @@
use super::DEPRECATED_SEMVER;
use clippy_utils::diagnostics::span_lint;
use rustc_ast::{LitKind, MetaItemLit};
use rustc_lint::LateContext;
use rustc_lint::EarlyContext;
use rustc_span::Span;
use semver::Version;
pub(super) fn check(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
pub(super) fn check(cx: &EarlyContext<'_>, span: Span, lit: &MetaItemLit) {
if let LitKind::Str(is, _) = lit.kind {
if is.as_str() == "TBD" || Version::parse(is.as_str()).is_ok() {
return;

View File

@ -2,12 +2,12 @@
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_ast::{Attribute, MetaItem};
use rustc_data_structures::fx::FxHashMap;
use rustc_lint::LateContext;
use rustc_lint::EarlyContext;
use rustc_span::{Span, sym};
use std::collections::hash_map::Entry;
fn emit_if_duplicated(
cx: &LateContext<'_>,
cx: &EarlyContext<'_>,
attr: &MetaItem,
attr_paths: &mut FxHashMap<String, Span>,
complete_path: String,
@ -26,7 +26,7 @@ fn emit_if_duplicated(
}
fn check_duplicated_attr(
cx: &LateContext<'_>,
cx: &EarlyContext<'_>,
attr: &MetaItem,
attr_paths: &mut FxHashMap<String, Span>,
parent: &mut Vec<String>,
@ -65,7 +65,7 @@ fn check_duplicated_attr(
}
}
pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) {
let mut attr_paths = FxHashMap::default();
for attr in attrs {

View File

@ -3,7 +3,7 @@
use rustc_ast::{AttrKind, AttrStyle, Attribute};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use rustc_lint::{LateContext, LintContext};
use rustc_lint::{EarlyContext, LintContext};
use rustc_span::source_map::SourceMap;
use rustc_span::{SourceFile, Span, Symbol};
@ -32,7 +32,7 @@ fn from(value: &AttrKind) -> Self {
}
}
pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute]) {
pub(super) fn check(cx: &EarlyContext<'_>, item_span: Span, attrs: &[Attribute]) {
let mut inner_attr_kind: FxHashSet<SimpleAttrKind> = FxHashSet::default();
let mut outer_attr_kind: FxHashSet<SimpleAttrKind> = FxHashSet::default();
@ -64,7 +64,7 @@ pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute])
}
}
fn lint_mixed_attrs(cx: &LateContext<'_>, attrs: &[Attribute]) {
fn lint_mixed_attrs(cx: &EarlyContext<'_>, attrs: &[Attribute]) {
let mut attrs_iter = attrs.iter().filter(|attr| !attr.span.from_expansion());
let span = if let (Some(first), Some(last)) = (attrs_iter.next(), attrs_iter.last()) {
first.span.with_hi(last.span.hi())

View File

@ -14,8 +14,8 @@
use clippy_config::Conf;
use clippy_config::msrvs::{self, Msrv};
use rustc_ast::{Attribute, MetaItemInner, MetaItemKind};
use rustc_hir::{ImplItem, Item, ItemKind, TraitItem};
use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind};
use rustc_hir::{ImplItem, Item, TraitItem};
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::sym;
@ -414,15 +414,7 @@ pub struct Attributes {
}
impl_lint_pass!(Attributes => [
ALLOW_ATTRIBUTES,
ALLOW_ATTRIBUTES_WITHOUT_REASON,
INLINE_ALWAYS,
DEPRECATED_SEMVER,
USELESS_ATTRIBUTE,
BLANKET_CLIPPY_RESTRICTION_LINTS,
SHOULD_PANIC_WITHOUT_EXPECT,
MIXED_ATTRIBUTES_STYLE,
DUPLICATED_ATTRIBUTES,
]);
impl Attributes {
@ -434,53 +426,11 @@ pub fn new(conf: &'static Conf) -> Self {
}
impl<'tcx> LateLintPass<'tcx> for Attributes {
fn check_crate(&mut self, cx: &LateContext<'tcx>) {
blanket_clippy_restriction_lints::check_command_line(cx);
duplicated_attributes::check(cx, cx.tcx.hir().krate_attrs());
}
fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
if let Some(items) = &attr.meta_item_list() {
if let Some(ident) = attr.ident() {
if is_lint_level(ident.name, attr.id) {
blanket_clippy_restriction_lints::check(cx, ident.name, items);
}
if matches!(ident.name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
allow_attributes::check(cx, attr);
}
if matches!(ident.name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION)
{
allow_attributes_without_reason::check(cx, ident.name, items, attr);
}
if items.is_empty() || !attr.has_name(sym::deprecated) {
return;
}
for item in items {
if let MetaItemInner::MetaItem(mi) = &item
&& let MetaItemKind::NameValue(lit) = &mi.kind
&& mi.has_name(sym::since)
{
deprecated_semver::check(cx, item.span(), lit);
}
}
}
}
if attr.has_name(sym::should_panic) {
should_panic_without_expect::check(cx, attr);
}
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
if is_relevant_item(cx, item) {
inline_always::check(cx, item.span, item.ident.name, attrs);
}
match item.kind {
ItemKind::ExternCrate(..) | ItemKind::Use(..) => useless_attribute::check(cx, item, attrs),
_ => {},
}
mixed_attributes_style::check(cx, item.span, attrs);
duplicated_attributes::check(cx, attrs);
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
@ -526,3 +476,77 @@ fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
extract_msrv_attr!(EarlyContext);
}
pub struct PostExpansionEarlyAttributes {
msrv: Msrv,
}
impl PostExpansionEarlyAttributes {
pub fn new(conf: &'static Conf) -> Self {
Self {
msrv: conf.msrv.clone(),
}
}
}
impl_lint_pass!(PostExpansionEarlyAttributes => [
ALLOW_ATTRIBUTES,
ALLOW_ATTRIBUTES_WITHOUT_REASON,
DEPRECATED_SEMVER,
USELESS_ATTRIBUTE,
BLANKET_CLIPPY_RESTRICTION_LINTS,
SHOULD_PANIC_WITHOUT_EXPECT,
MIXED_ATTRIBUTES_STYLE,
DUPLICATED_ATTRIBUTES,
]);
impl EarlyLintPass for PostExpansionEarlyAttributes {
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
blanket_clippy_restriction_lints::check_command_line(cx);
duplicated_attributes::check(cx, &krate.attrs);
}
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
if let Some(items) = &attr.meta_item_list() {
if let Some(ident) = attr.ident() {
if matches!(ident.name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
allow_attributes::check(cx, attr);
}
if matches!(ident.name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION)
{
allow_attributes_without_reason::check(cx, ident.name, items, attr);
}
if is_lint_level(ident.name, attr.id) {
blanket_clippy_restriction_lints::check(cx, ident.name, items);
}
if items.is_empty() || !attr.has_name(sym::deprecated) {
return;
}
for item in items {
if let MetaItemInner::MetaItem(mi) = &item
&& let MetaItemKind::NameValue(lit) = &mi.kind
&& mi.has_name(sym::since)
{
deprecated_semver::check(cx, item.span(), lit);
}
}
}
}
if attr.has_name(sym::should_panic) {
should_panic_without_expect::check(cx, attr);
}
}
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &'_ ast::Item) {
match item.kind {
ast::ItemKind::ExternCrate(..) | ast::ItemKind::Use(..) => useless_attribute::check(cx, item, &item.attrs),
_ => {},
}
mixed_attributes_style::check(cx, item.span, &item.attrs);
duplicated_attributes::check(cx, &item.attrs);
}
extract_msrv_attr!(EarlyContext);
}

View File

@ -4,12 +4,12 @@
use rustc_ast::tokenstream::TokenTree;
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind};
use rustc_errors::Applicability;
use rustc_lint::LateContext;
use rustc_lint::EarlyContext;
use rustc_span::sym;
pub(super) fn check(cx: &LateContext<'_>, attr: &Attribute) {
pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
if let AttrKind::Normal(normal_attr) = &attr.kind {
if let AttrArgs::Eq(_, AttrArgsEq::Hir(_)) = &normal_attr.item.args {
if let AttrArgs::Eq(_, AttrArgsEq::Ast(_)) = &normal_attr.item.args {
// `#[should_panic = ".."]` found, good
return;
}

View File

@ -1,15 +1,14 @@
use super::USELESS_ATTRIBUTE;
use super::utils::{extract_clippy_lint, is_lint_level, is_word};
use super::{Attribute, USELESS_ATTRIBUTE};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{SpanRangeExt, first_line_of_span};
use rustc_ast::MetaItemInner;
use rustc_ast::{Attribute, Item, ItemKind, MetaItemInner};
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LintContext};
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::sym;
pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute]) {
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
for attr in attrs {

View File

@ -30,7 +30,8 @@
#[clippy::version = "1.35.0"]
pub COGNITIVE_COMPLEXITY,
nursery,
"functions that should be split up into multiple functions"
"functions that should be split up into multiple functions",
@eval_always = true
}
pub struct CognitiveComplexity {

26
clippy_lints/src/ctfe.rs Normal file
View File

@ -0,0 +1,26 @@
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::Span;
declare_lint_pass! {
/// Ensures that Constant-time Function Evaluation is being done (specifically, MIR lint passes).
/// As Clippy deactivates codegen, this lint ensures that CTFE (used in hard errors) is still ran.
ClippyCtfe => []
}
impl<'tcx> LateLintPass<'tcx> for ClippyCtfe {
fn check_fn(
&mut self,
cx: &LateContext<'_>,
_: FnKind<'tcx>,
_: &'tcx FnDecl<'tcx>,
_: &'tcx Body<'tcx>,
_: Span,
defid: LocalDefId,
) {
cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint
}
}

View File

@ -4,19 +4,21 @@ macro_rules! declare_clippy_lint {
(@
$(#[doc = $lit:literal])*
pub $lint_name:ident,
$category:ident,
$level:ident,
$lintcategory:expr,
$desc:literal,
$version_expr:expr,
$version_lit:literal
$(, $eval_always: literal)?
) => {
rustc_session::declare_tool_lint! {
$(#[doc = $lit])*
#[clippy::version = $version_lit]
pub clippy::$lint_name,
$category,
$level,
$desc,
report_in_external_macro:true
$(, @eval_always = $eval_always)?
}
pub(crate) static ${concat($lint_name, _INFO)}: &'static crate::LintInfo = &crate::LintInfo {
@ -33,11 +35,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
restriction,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Allow, crate::LintCategory::Restriction, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -46,12 +50,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
style,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Warn, crate::LintCategory::Style, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -60,11 +65,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
correctness,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Deny, crate::LintCategory::Correctness, $desc,
Some($version), $version
$(, $eval_always)?
}
};
@ -74,11 +81,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
perf,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Warn, crate::LintCategory::Perf, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -87,11 +96,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
complexity,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Warn, crate::LintCategory::Complexity, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -100,11 +111,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
suspicious,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Warn, crate::LintCategory::Suspicious, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -113,11 +126,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
nursery,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Allow, crate::LintCategory::Nursery, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -126,11 +141,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
pedantic,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Allow, crate::LintCategory::Pedantic, $desc,
Some($version), $version
$(, $eval_always)?
}
};
(
@ -139,11 +156,13 @@ macro_rules! declare_clippy_lint {
pub $lint_name:ident,
cargo,
$desc:literal
$(, @eval_always = $eval_always: literal)?
) => {
declare_clippy_lint! {@
$(#[doc = $lit])*
pub $lint_name, Allow, crate::LintCategory::Cargo, $desc,
Some($version), $version
$(, $eval_always)?
}
};

View File

@ -166,7 +166,7 @@ macro_rules! declare_with_version {
#[clippy::version = ""]
("clippy::positional_named_format_parameters", "named_arguments_used_positionally"),
#[clippy::version = ""]
("clippy::temporary_cstring_as_ptr", "temporary_cstring_as_ptr"),
("clippy::temporary_cstring_as_ptr", "dangling_pointers_from_temporaries"),
#[clippy::version = ""]
("clippy::undropped_manually_drops", "undropped_manually_drops"),
#[clippy::version = ""]

View File

@ -418,7 +418,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let (required_refs, msg) = if can_auto_borrow {
(1, if deref_count == 1 { borrow_msg } else { deref_msg })
} else if let Some(&Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
kind: Adjust::Borrow(AutoBorrow::Ref(mutability)),
..
}) = next_adjust
&& matches!(mutability, AutoBorrowMutability::Mut { .. })

View File

@ -326,7 +326,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
// If the current self type doesn't implement Copy (due to generic constraints), search to see if
// there's a Copy impl for any instance of the adt.
if !is_copy(cx, ty) {
if ty_subs.non_erasable_generics(cx.tcx, ty_adt.did()).next().is_some() {
if ty_subs.non_erasable_generics().next().is_some() {
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
impls.iter().any(|&id| {
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)

View File

@ -64,7 +64,7 @@ impl LateLintPass<'_> for EmptyEnum {
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
if let ItemKind::Enum(..) = item.kind
// Only suggest the `never_type` if the feature is enabled
&& cx.tcx.features().never_type
&& cx.tcx.features().never_type()
&& let Some(adt) = cx.tcx.type_of(item.owner_id).instantiate_identity().ty_adt_def()
&& adt.variants().is_empty()
{

View File

@ -203,11 +203,16 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
// 'cuz currently nothing changes after deleting this check.
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
}) {
match cx.tcx.infer_ctxt().build().err_ctxt().type_implements_fn_trait(
cx.param_env,
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
ty::PredicatePolarity::Positive,
) {
match cx
.tcx
.infer_ctxt()
.build(cx.typing_mode())
.err_ctxt()
.type_implements_fn_trait(
cx.param_env,
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
ty::PredicatePolarity::Positive,
) {
// Mutable closure is used after current expr; we cannot consume it.
Ok((ClosureKind::FnMut, _)) => snippet = format!("&mut {snippet}"),
Ok((ClosureKind::Fn, _)) if !callee_ty_raw.is_ref() => {

View File

@ -117,7 +117,7 @@ fn check_needless_must_use(
} else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
// Ignore async functions unless Future::Output type is a must_use type
if sig.header.is_async() {
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
if let Some(future_ty) = infcx.err_ctxt().get_impl_future_output_ty(return_ty(cx, item_id))
&& !is_must_use_ty(cx, future_ty)
{

View File

@ -74,7 +74,7 @@ fn check_fn(
if is_future {
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
let span = decl.output.span();
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let cause = traits::ObligationCause::misc(span, fn_def_id);
ocx.register_bound(cause, cx.param_env, ret_ty, send_trait);

View File

@ -3,7 +3,7 @@
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_hir::def_id::DefId;
use rustc_hir::{
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier, TyKind,
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind,
WherePredicate,
};
use rustc_hir_analysis::lower_ty;
@ -190,15 +190,6 @@ fn is_same_generics<'tcx>(
.enumerate()
.skip(1) // skip `Self` implicit arg
.all(|(arg_index, arg)| {
if [
implied_by_generics.host_effect_index,
implied_generics.host_effect_index,
]
.contains(&Some(arg_index))
{
// skip host effect params in determining whether generics are same
return true;
}
if let Some(ty) = arg.as_type() {
if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind()
// `index == 0` means that it's referring to `Self`,
@ -243,7 +234,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
.iter()
.filter_map(|bound| {
if let GenericBound::Trait(poly_trait) = bound
&& let TraitBoundModifier::None = poly_trait.modifiers
&& let TraitBoundModifiers::NONE = poly_trait.modifiers
&& let [.., path] = poly_trait.trait_ref.path.segments
&& poly_trait.bound_generic_params.is_empty()
&& let Some(trait_def_id) = path.res.opt_def_id()
@ -309,7 +300,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
// simply comparing trait `DefId`s won't be enough. We also need to compare the generics.
for (index, bound) in bounds.iter().enumerate() {
if let GenericBound::Trait(poly_trait) = bound
&& let TraitBoundModifier::None = poly_trait.modifiers
&& let TraitBoundModifiers::NONE = poly_trait.modifiers
&& let [.., path] = poly_trait.trait_ref.path.segments
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
&& let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)

View File

@ -114,7 +114,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Some(range) = higher::Range::hir(index) {
// Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
if let ty::Array(_, s) = ty.kind() {
let size: u128 = if let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) {
let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {
size.into()
} else {
return;
@ -183,7 +183,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
&& let ty::Uint(utype) = cx.typeck_results().expr_ty(index).kind()
&& *utype == ty::UintTy::Usize
&& let ty::Array(_, s) = ty.kind()
&& let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env)
&& let Some(size) = s.try_to_target_usize(cx.tcx)
{
// get constant offset and check whether it is in bounds
let off = usize::try_from(off).unwrap();

View File

@ -56,7 +56,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
&& !item.span.from_expansion()
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let ty::Array(element_type, cst) = ty.kind()
&& let Ok((_, ty::ValTree::Leaf(element_count))) = cst.eval(cx.tcx, ParamEnv::empty(), item.span)
&& let Ok((_, ty::ValTree::Leaf(element_count))) = cst.eval_valtree(cx.tcx, ParamEnv::empty(), item.span)
&& let element_count = element_count.to_target_usize(cx.tcx)
&& let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
&& u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)

View File

@ -65,6 +65,7 @@
#[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
mod utils;
pub mod ctfe; // Very important lint, do not remove (rust#125116)
pub mod declared_lints;
pub mod deprecated_lints;
@ -412,6 +413,8 @@
pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
// NOTE: Do not add any more pre-expansion passes. These should be removed eventually.
store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes::new(conf)));
store.register_early_pass(move || Box::new(attrs::PostExpansionEarlyAttributes::new(conf)));
}
#[derive(Default)]
@ -607,6 +610,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(utils::internal_lints::slow_symbol_comparisons::SlowSymbolComparisons));
}
store.register_late_pass(|_| Box::new(ctfe::ClippyCtfe));
store.register_late_pass(move |_| Box::new(operators::arithmetic_side_effects::ArithmeticSideEffects::new(conf)));
store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
store.register_late_pass(|_| Box::new(utils::author::Author));

View File

@ -420,15 +420,6 @@ fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) {
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
match ty.kind {
TyKind::OpaqueDef(opaque, bounds) => {
let len = self.lts.len();
self.visit_opaque_ty(opaque);
self.lts.truncate(len);
self.lts.extend(bounds.iter().filter_map(|bound| match bound {
&GenericArg::Lifetime(l) => Some(l),
_ => None,
}));
},
TyKind::BareFn(&BareFnTy { decl, .. }) => {
let mut sub_visitor = RefVisitor::new(self.cx);
sub_visitor.visit_fn_decl(decl);

View File

@ -53,7 +53,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<
[] => AdjustKind::None,
&[
Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
..
},
] => AdjustKind::borrow(mutbl),
@ -62,7 +62,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<
kind: Adjust::Deref(_), ..
},
Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
target,
},
] => {

View File

@ -29,11 +29,7 @@ pub(super) fn check(
if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) {
return;
}
} else if count
.try_eval_target_usize(cx.tcx, cx.param_env)
.map_or(true, |x| x > 32)
&& !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN)
{
} else if count.try_to_target_usize(cx.tcx).map_or(true, |x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) {
return;
}
}
@ -199,7 +195,7 @@ fn is_ref_iterable<'tcx>(
kind: Adjust::Deref(_), ..
},
Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
target,
},
..,
@ -236,7 +232,7 @@ fn is_ref_iterable<'tcx>(
},
&[
Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
target,
},
..,

View File

@ -158,14 +158,11 @@ fn is_never_return(ret_ty: FnRetTy<'_>) -> bool {
match hir_ty.kind {
TyKind::Never => true,
TyKind::OpaqueDef(
hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::AsyncFn { .. },
bounds,
..
},
_,
) => {
TyKind::OpaqueDef(hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::AsyncFn { .. },
bounds,
..
}) => {
if let Some(trait_ref) = bounds.iter().find_map(|b| b.trait_ref())
&& let Some(segment) = trait_ref
.path

View File

@ -472,7 +472,7 @@ fn extract_lit_value(expr: &Expr<'_>) -> Option<u128> {
let arr_ty = cx.typeck_results().expr_ty(arr).peel_refs();
if let ty::Array(_, s) = arr_ty.kind() {
let size: u128 = if let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) {
let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {
size.into()
} else {
return false;

View File

@ -80,7 +80,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {
if bk == ty::BorrowKind::MutBorrow {
if bk == ty::BorrowKind::Mutable {
if let PlaceBase::Local(id) = cmt.place.base {
if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {
self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id));

View File

@ -207,7 +207,7 @@ fn is_end_eq_array_len<'tcx>(
if let ExprKind::Lit(lit) = end.kind
&& let ast::LitKind::Int(end_int, _) = lit.node
&& let ty::Array(_, arr_len_const) = indexed_ty.kind()
&& let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env)
&& let Some(arr_len) = arr_len_const.try_to_target_usize(cx.tcx)
{
return match limits {
ast::RangeLimits::Closed => end_int.get() + 1 >= arr_len.into(),

View File

@ -4,9 +4,11 @@
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
FnRetTy, GenericArg, GenericBound, ImplItem, Item, LifetimeName, Node, TraitRef, Ty, TyKind,
FnRetTy, GenericBound, ImplItem, Item, Node, OpaqueTy, TraitRef, Ty, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::{Span, sym};
@ -44,21 +46,22 @@ fn check_fn(
decl: &'tcx FnDecl<'_>,
body: &'tcx Body<'_>,
span: Span,
def_id: LocalDefId,
fn_def_id: LocalDefId,
) {
if let Some(header) = kind.header()
&& !header.asyncness.is_async()
// Check that this function returns `impl Future`
&& let FnRetTy::Return(ret_ty) = decl.output
&& let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty)
&& let TyKind::OpaqueDef(opaque) = ret_ty.kind
&& let Some(trait_ref) = future_trait_ref(cx, opaque)
&& let Some(output) = future_output_ty(trait_ref)
&& captures_all_lifetimes(decl.inputs, &output_lifetimes)
&& captures_all_lifetimes(cx, fn_def_id, opaque.def_id)
// Check that the body of the function consists of one async block
&& let ExprKind::Block(block, _) = body.value.kind
&& block.stmts.is_empty()
&& let Some(closure_body) = desugared_async_block(cx, block)
&& let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) =
cx.tcx.hir_node_by_def_id(def_id)
cx.tcx.hir_node_by_def_id(fn_def_id)
{
let header_span = span.with_hi(ret_ty.span.hi());
@ -101,32 +104,16 @@ fn check_fn(
}
}
fn future_trait_ref<'tcx>(
cx: &LateContext<'tcx>,
ty: &'tcx Ty<'tcx>,
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
if let GenericBound::Trait(poly) = bound {
Some(&poly.trait_ref)
} else {
None
}
})
&& trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait()
fn future_trait_ref<'tcx>(cx: &LateContext<'tcx>, opaque: &'tcx OpaqueTy<'tcx>) -> Option<&'tcx TraitRef<'tcx>> {
if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
if let GenericBound::Trait(poly) = bound {
Some(&poly.trait_ref)
} else {
None
}
}) && trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait()
{
let output_lifetimes = bounds
.iter()
.filter_map(|bound| {
if let GenericArg::Lifetime(lt) = bound {
Some(lt.res)
} else {
None
}
})
.collect();
return Some((trait_ref, output_lifetimes));
return Some(trait_ref);
}
None
@ -145,27 +132,37 @@ fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'t
None
}
fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName]) -> bool {
let input_lifetimes: Vec<LifetimeName> = inputs
.iter()
.filter_map(|ty| {
if let TyKind::Ref(lt, _) = ty.kind {
Some(lt.res)
} else {
None
}
})
.collect();
fn captures_all_lifetimes(cx: &LateContext<'_>, fn_def_id: LocalDefId, opaque_def_id: LocalDefId) -> bool {
let early_input_params = ty::GenericArgs::identity_for_item(cx.tcx, fn_def_id);
let late_input_params = cx.tcx.late_bound_vars(cx.tcx.local_def_id_to_hir_id(fn_def_id));
// The lint should trigger in one of these cases:
// - There are no input lifetimes
// - There's only one output lifetime bound using `+ '_`
// - All input lifetimes are explicitly bound to the output
input_lifetimes.is_empty()
|| (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Infer))
|| input_lifetimes
.iter()
.all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt))
let num_early_lifetimes = early_input_params
.iter()
.filter(|param| param.as_region().is_some())
.count();
let num_late_lifetimes = late_input_params
.iter()
.filter(|param_kind| matches!(param_kind, ty::BoundVariableKind::Region(_)))
.count();
// There is no lifetime, so they are all captured.
if num_early_lifetimes == 0 && num_late_lifetimes == 0 {
return true;
}
// By construction, each captured lifetime only appears once in `opaque_captured_lifetimes`.
let num_captured_lifetimes = cx
.tcx
.opaque_captured_lifetimes(opaque_def_id)
.iter()
.filter(|&(lifetime, _)| {
matches!(
*lifetime,
ResolvedArg::EarlyBound(_) | ResolvedArg::LateBound(ty::INNERMOST, _, _)
)
})
.count();
num_captured_lifetimes == num_early_lifetimes + num_late_lifetimes
}
fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {

View File

@ -111,11 +111,7 @@ fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr);
match expr_ty.peel_refs().kind() {
ty::Uint(_) => true,
ty::Int(_) => cx
.tcx
.features()
.declared_features
.contains(&Symbol::intern("int_roundings")),
ty::Int(_) => cx.tcx.features().enabled(Symbol::intern("int_roundings")),
_ => false,
}

View File

@ -114,7 +114,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect();
for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) {
if matches!(arm2.pat.kind, PatKind::Wild) {
if !cx.tcx.features().non_exhaustive_omitted_patterns_lint
if !cx.tcx.features().non_exhaustive_omitted_patterns_lint()
|| is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id)
{
let arm_span = adjusted_arm_span(cx, arm1.span);

View File

@ -251,7 +251,7 @@ fn emit_redundant_guards<'tcx>(
fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
for_each_expr_without_closures(expr, |expr| {
if match expr.kind {
ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat,
ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat(),
ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => {
// Allow ctors
matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..))

View File

@ -11,7 +11,7 @@
use rustc_hir::intravisit::{Visitor, walk_pat};
use rustc_hir::{Arm, Expr, ExprKind, HirId, Node, Pat, PatKind, QPath, StmtKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, AdtDef, ParamEnv, TyCtxt, TypeckResults, VariantDef};
use rustc_middle::ty::{self, AdtDef, TyCtxt, TypeckResults, VariantDef};
use rustc_span::{Span, sym};
use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
@ -67,7 +67,6 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tc
if v.has_enum {
let cx = PatCtxt {
tcx: cx.tcx,
param_env: cx.param_env,
typeck,
arena: DroplessArena::default(),
};
@ -185,7 +184,6 @@ fn visit_pat(&mut self, pat: &'tcx Pat<'_>) -> Self::Result {
/// The context needed to manipulate a `PatState`.
struct PatCtxt<'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
typeck: &'tcx TypeckResults<'tcx>,
arena: DroplessArena,
}
@ -337,7 +335,7 @@ fn add_pat<'tcx>(&mut self, cx: &'a PatCtxt<'tcx>, pat: &'tcx Pat<'_>) -> bool {
if match *cx.typeck.pat_ty(pat).peel_refs().kind() {
ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()),
ty::Tuple(tys) => !tys.is_empty(),
ty::Array(_, len) => len.try_eval_target_usize(cx.tcx, cx.param_env) != Some(1),
ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1),
ty::Slice(..) => true,
_ => false,
} =>
@ -356,7 +354,7 @@ fn add_pat<'tcx>(&mut self, cx: &'a PatCtxt<'tcx>, pat: &'tcx Pat<'_>) -> bool {
},
PatKind::Slice([sub_pat], _, []) | PatKind::Slice([], _, [sub_pat])
if let ty::Array(_, len) = *cx.typeck.pat_ty(pat).kind()
&& len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(1) =>
&& len.try_to_target_usize(cx.tcx) == Some(1) =>
{
self.add_pat(cx, sub_pat)
},

View File

@ -29,16 +29,13 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) ->
if cx.tcx.is_diagnostic_item(sym::ArrayIntoIter, did) {
// For array::IntoIter<T, const N: usize>, the length is the second generic
// parameter.
substs
.const_at(1)
.try_eval_target_usize(cx.tcx, cx.param_env)
.map(u128::from)
substs.const_at(1).try_to_target_usize(cx.tcx).map(u128::from)
} else if cx.tcx.is_diagnostic_item(sym::SliceIter, did)
&& let ExprKind::MethodCall(_, recv, ..) = iter.kind
{
if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {
// For slice::Iter<'_, T>, the receiver might be an array literal: [1,2,3].iter().skip(..)
len.try_eval_target_usize(cx.tcx, cx.param_env).map(u128::from)
len.try_to_target_usize(cx.tcx).map(u128::from)
} else if let Some(args) = VecArgs::hir(cx, expr_or_init(cx, recv)) {
match args {
VecArgs::Vec(vec) => vec.len().try_into().ok(),

View File

@ -137,7 +137,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
_ if matches!(
typeck.expr_adjustments(prev_expr).first(),
Some(Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not))
kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not))
| Adjust::Deref(_),
..
})
@ -230,7 +230,7 @@ fn check_use<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (UseKind<'tcx>,
if use_cx
.adjustments
.first()
.is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not)))) =>
.is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)))) =>
{
UseKind::AutoBorrowed
},

View File

@ -5293,7 +5293,7 @@ fn lifetime_param_cond(&self, impl_item: &hir::ImplItem<'_>) -> bool {
}
#[rustfmt::skip]
static TRAIT_METHODS: [ShouldImplTraitCase; 30] = [
const TRAIT_METHODS: [ShouldImplTraitCase; 30] = [
ShouldImplTraitCase::new("std::ops::Add", "add", 2, FN_HEADER, SelfKind::Value, OutType::Any, true),
ShouldImplTraitCase::new("std::convert::AsMut", "as_mut", 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true),
ShouldImplTraitCase::new("std::convert::AsRef", "as_ref", 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true),

View File

@ -568,7 +568,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx
.infer_ctxt()
.build()
.build(cx.typing_mode())
.predicate_must_hold_modulo_regions(&obligation)
}) {
return false;

View File

@ -18,7 +18,7 @@ fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
ty::Slice(_) => true,
ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => may_slice(cx, boxed),
ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec),
ty::Array(_, size) => size.try_eval_target_usize(cx.tcx, cx.param_env).is_some(),
ty::Array(_, size) => size.try_to_target_usize(cx.tcx).is_some(),
ty::Ref(_, inner, _) => may_slice(cx, *inner),
_ => false,
}

View File

@ -2,6 +2,7 @@
use rustc_ast::ast;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::AssocItemContainer;
use rustc_session::declare_lint_pass;
use rustc_span::{Span, sym};
@ -138,7 +139,6 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
use rustc_middle::ty::{ImplContainer, TraitContainer};
if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable_or_proc_macro(cx) {
return;
}
@ -156,8 +156,8 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::Impl
let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
let container_id = assoc_item.container_id(cx.tcx);
let trait_def_id = match assoc_item.container {
TraitContainer => Some(container_id),
ImplContainer => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id),
AssocItemContainer::Trait => Some(container_id),
AssocItemContainer::Impl => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id),
};
if let Some(trait_def_id) = trait_def_id {

View File

@ -278,7 +278,7 @@ fn needless_borrow_count<'tcx>(
let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]);
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
infcx.predicate_must_hold_modulo_regions(&obligation)
})
};

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::Applicability;
use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_hir::{GenericBound, Generics, PolyTraitRef, TraitBoundModifier, WherePredicate};
use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicate};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{ClauseKind, PredicatePolarity};
use rustc_session::declare_lint_pass;
@ -118,13 +118,13 @@ fn check_generics(&mut self, cx: &LateContext<'_>, generics: &Generics<'_>) {
let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)
.filter(|bound| {
bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait)
&& bound.trait_bound.modifiers == TraitBoundModifier::Maybe
&& matches!(bound.trait_bound.modifiers.polarity, BoundPolarity::Maybe(_))
})
.map(|bound| (bound.param, bound))
.collect();
for bound in type_param_bounds(generics) {
if bound.trait_bound.modifiers == TraitBoundModifier::None
if bound.trait_bound.modifiers == TraitBoundModifiers::NONE
&& let Some(sized_bound) = maybe_sized_params.get(&bound.param)
&& let Some(path) = path_to_sized_bound(cx, bound.trait_bound)
{

View File

@ -417,8 +417,8 @@ fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId, borrow: ty::Bor
// a closure, it'll return this variant whereas if you have just an index access, it'll
// return `ImmBorrow`. So if there is "Unique" and it's a mutable reference, we add it
// to the mutably used variables set.
if borrow == ty::BorrowKind::MutBorrow
|| (borrow == ty::BorrowKind::UniqueImmBorrow && base_ty.ref_mutability() == Some(Mutability::Mut))
if borrow == ty::BorrowKind::Mutable
|| (borrow == ty::BorrowKind::UniqueImmutable && base_ty.ref_mutability() == Some(Mutability::Mut))
{
self.add_mutably_used_var(*vid);
} else if self.is_in_unsafe_block(id) {
@ -426,7 +426,7 @@ fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId, borrow: ty::Bor
// upon!
self.add_mutably_used_var(*vid);
}
} else if borrow == ty::ImmBorrow {
} else if borrow == ty::BorrowKind::Immutable {
// If there is an `async block`, it'll contain a call to a closure which we need to
// go into to ensure all "mutate" checks are found.
if let Node::Expr(Expr {

View File

@ -159,8 +159,12 @@ fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
// Remove `impl Future<Output = T>` to get `T`
if cx.tcx.ty_is_opaque_future(ret_ty)
&& let Some(true_ret_ty) =
cx.tcx.infer_ctxt().build().err_ctxt().get_impl_future_output_ty(ret_ty)
&& let Some(true_ret_ty) = cx
.tcx
.infer_ctxt()
.build(cx.typing_mode())
.err_ctxt()
.get_impl_future_output_ty(ret_ty)
{
ret_ty = true_ret_ty;
}

View File

@ -102,7 +102,7 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet {
struct S(HirIdSet);
impl Delegate<'_> for S {
fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) {
if matches!(kind, BorrowKind::ImmBorrow | BorrowKind::UniqueImmBorrow) {
if matches!(kind, BorrowKind::Immutable | BorrowKind::UniqueImmutable) {
self.0.insert(match place.place.base {
PlaceBase::Local(id) => id,
PlaceBase::Upvar(id) => id.var_path.hir_id,
@ -127,7 +127,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet {
struct S(HirIdSet);
impl Delegate<'_> for S {
fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) {
if matches!(kind, BorrowKind::MutBorrow) {
if matches!(kind, BorrowKind::Mutable) {
self.0.insert(match place.place.base {
PlaceBase::Local(id) => id,
PlaceBase::Upvar(id) => id.var_path.hir_id,

View File

@ -695,7 +695,7 @@ fn matches_preds<'tcx>(
ty: Ty<'tcx>,
preds: &'tcx [ty::PolyExistentialPredicate<'tcx>],
) -> bool {
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
preds
.iter()
.all(|&p| match cx.tcx.instantiate_bound_regions_with_erased(p) {

View File

@ -110,7 +110,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
) || cx.typeck_results().expr_adjustments(expr).first().map_or(false, |a| {
matches!(
a.kind,
Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. }))
Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. }))
)
}) || (matches!(
cx.typeck_results().expr_ty(indexed).ref_mutability(),

View File

@ -2,7 +2,7 @@
use clippy_utils::has_repr_attr;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{Const, FeedConstTy};
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -55,16 +55,14 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
if let ItemKind::Struct(data, _) = &item.kind
// First check if last field is an array
&& let Some(last_field) = data.fields().last()
&& let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind
// Then check if that array is zero-sized
&& let length = Const::from_const_arg(cx.tcx, length, FeedConstTy::No)
&& let length = length.try_eval_target_usize(cx.tcx, cx.param_env)
&& let Some(length) = length
&& let field_ty = cx
.tcx
.normalize_erasing_regions(cx.param_env, cx.tcx.type_of(last_field.def_id).instantiate_identity())
&& let ty::Array(_, array_len) = *field_ty.kind()
&& let Some(0) = array_len.try_to_target_usize(cx.tcx)
{
length == 0
true
} else {
false
}

View File

@ -10,8 +10,8 @@
use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::{
GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
TraitBoundModifier, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
@ -233,7 +233,7 @@ impl TraitBounds {
fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {
if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE)
&& let GenericBound::Trait(tr) = bound
&& let TraitBoundModifier::Maybe = tr.modifiers
&& let BoundPolarity::Maybe(_) = tr.modifiers.polarity
{
cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id()
} else {
@ -374,12 +374,12 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
struct ComparableTraitRef<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
trait_ref: &'tcx TraitRef<'tcx>,
modifier: TraitBoundModifier,
modifiers: TraitBoundModifiers,
}
impl PartialEq for ComparableTraitRef<'_, '_> {
fn eq(&self, other: &Self) -> bool {
self.modifier == other.modifier
SpanlessEq::eq_modifiers(self.modifiers, other.modifiers)
&& SpanlessEq::new(self.cx)
.paths_by_resolution()
.eq_path(self.trait_ref.path, other.trait_ref.path)
@ -390,8 +390,8 @@ impl Hash for ComparableTraitRef<'_, '_> {
fn hash<H: Hasher>(&self, state: &mut H) {
let mut s = SpanlessHash::new(self.cx).paths_by_resolution();
s.hash_path(self.trait_ref.path);
s.hash_modifiers(self.modifiers);
state.write_u64(s.finish());
self.modifier.hash(state);
}
}
@ -400,7 +400,7 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'
let trait_path = t.trait_ref.path;
let trait_span = {
let path_span = trait_path.span;
if let TraitBoundModifier::Maybe = t.modifiers {
if let BoundPolarity::Maybe(_) = t.modifiers.polarity {
path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?`
} else {
path_span
@ -427,7 +427,7 @@ fn rollup_traits<'cx, 'tcx>(
ComparableTraitRef {
cx,
trait_ref: &t.trait_ref,
modifier: t.modifiers,
modifiers: t.modifiers,
},
t.span,
))

View File

@ -190,7 +190,7 @@ fn all_bindings_are_for_conv<'tcx>(
tys.len() == elements.len() && tys.iter().chain(final_tys.iter().copied()).all_equal()
},
(ToType::Tuple, ty::Array(ty, len)) => {
let Some(len) = len.try_eval_target_usize(cx.tcx, cx.param_env) else { return false };
let Some(len) = len.try_to_target_usize(cx.tcx) else { return false };
len as usize == elements.len() && final_tys.iter().chain(once(ty)).all_equal()
},
_ => false,

View File

@ -217,7 +217,7 @@ fn is_option_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool {
impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> {
fn borrow(&mut self, cat: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {
if let ty::BorrowKind::MutBorrow = bk
if let ty::BorrowKind::Mutable = bk
&& is_potentially_local_place(self.local_id, &cat.place)
&& !is_option_as_mut_use(self.tcx, diag_expr_id)
{

View File

@ -114,7 +114,7 @@ fn into_iter_bound<'tcx>(
if !cx
.tcx
.infer_ctxt()
.build()
.build(cx.typing_mode())
.predicate_must_hold_modulo_regions(&obligation)
{
return None;

View File

@ -21,7 +21,7 @@
///
/// ### Why is this bad?
/// The compiler only knows lints via a `LintPass`. Without
/// putting a lint to a `LintPass::get_lints()`'s return, the compiler will not
/// putting a lint to a `LintPass::lint_vec()`'s return, the compiler will not
/// know the name of the lint.
///
/// ### Known problems
@ -159,8 +159,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let body = cx.tcx.hir().body_owned_by(
impl_item_refs
.iter()
.find(|iiref| iiref.ident.as_str() == "get_lints")
.expect("LintPass needs to implement get_lints")
.find(|iiref| iiref.ident.as_str() == "lint_vec")
.expect("LintPass needs to implement lint_vec")
.id
.owner_id
.def_id,

View File

@ -39,7 +39,7 @@ fn from(attr: &Attribute) -> Self {
struct IdentCollector(Vec<Ident>);
impl Visitor<'_> for IdentCollector {
fn visit_ident(&mut self, ident: Ident) {
self.0.push(ident);
fn visit_ident(&mut self, ident: &Ident) {
self.0.push(*ident);
}
}

View File

@ -21,7 +21,7 @@
ImplItem, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety,
TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource,
};
use rustc_lint::{LateContext, LintContext};
use rustc_lint::{EarlyContext, LateContext, LintContext};
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::symbol::{Ident, kw};
@ -435,11 +435,12 @@ fn span(&self) -> Span {
impl_with_search_pat!((_cx: LateContext<'tcx>, self: FieldDef<'_>) => field_def_search_pat(self));
impl_with_search_pat!((_cx: LateContext<'tcx>, self: Variant<'_>) => variant_search_pat(self));
impl_with_search_pat!((_cx: LateContext<'tcx>, self: Ty<'_>) => ty_search_pat(self));
impl_with_search_pat!((_cx: LateContext<'tcx>, self: Attribute) => attr_search_pat(self));
impl_with_search_pat!((_cx: LateContext<'tcx>, self: Ident) => ident_search_pat(*self));
impl_with_search_pat!((_cx: LateContext<'tcx>, self: Lit) => lit_search_pat(&self.node));
impl_with_search_pat!((_cx: LateContext<'tcx>, self: Path<'_>) => path_search_pat(self));
impl_with_search_pat!((_cx: EarlyContext<'tcx>, self: Attribute) => attr_search_pat(self));
impl<'cx> WithSearchPat<'cx> for (&FnKind<'cx>, &Body<'cx>, HirId, Span) {
type Context = LateContext<'cx>;

View File

@ -478,7 +478,7 @@ fn expr(&self, e: &Expr<'_>) -> Option<Constant<'tcx>> {
ExprKind::Tup(tup) => self.multi(tup).map(Constant::Tuple),
ExprKind::Repeat(value, _) => {
let n = match self.typeck.expr_ty(e).kind() {
ty::Array(_, n) => n.try_eval_target_usize(self.tcx, self.param_env)?,
ty::Array(_, n) => n.try_to_target_usize(self.tcx)?,
_ => span_bug!(e.span, "typeck error"),
};
self.expr(value).map(|v| Constant::Repeat(Box::new(v), n))
@ -559,7 +559,7 @@ pub fn eval_is_empty(&self, e: &Expr<'_>) -> Option<bool> {
ExprKind::Array(vec) => self.multi(vec).map(|v| v.is_empty()),
ExprKind::Repeat(..) => {
if let ty::Array(_, n) = self.typeck.expr_ty(e).kind() {
Some(n.try_eval_target_usize(self.tcx, self.param_env)? == 0)
Some(n.try_to_target_usize(self.tcx)? == 0)
} else {
span_bug!(e.span, "typeck error");
}

View File

@ -9,7 +9,8 @@
use rustc_hir::{
ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime,
LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind,
LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitBoundModifiers, Ty,
TyKind,
};
use rustc_lexer::{TokenKind, tokenize};
use rustc_lint::LateContext;
@ -126,6 +127,11 @@ pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_
pub fn eq_path_segments(&mut self, left: &[PathSegment<'_>], right: &[PathSegment<'_>]) -> bool {
self.inter_expr().eq_path_segments(left, right)
}
pub fn eq_modifiers(left: TraitBoundModifiers, right: TraitBoundModifiers) -> bool {
std::mem::discriminant(&left.constness) == std::mem::discriminant(&right.constness)
&& std::mem::discriminant(&left.polarity) == std::mem::discriminant(&right.polarity)
}
}
pub struct HirEqInterExpr<'a, 'b, 'tcx> {
@ -1143,6 +1149,12 @@ pub fn hash_path(&mut self, path: &Path<'_>) {
}
}
pub fn hash_modifiers(&mut self, modifiers: TraitBoundModifiers) {
let TraitBoundModifiers { constness, polarity } = modifiers;
std::mem::discriminant(&polarity).hash(&mut self.s);
std::mem::discriminant(&constness).hash(&mut self.s);
}
pub fn hash_stmt(&mut self, b: &Stmt<'_>) {
std::mem::discriminant(&b.kind).hash(&mut self.s);
@ -1219,16 +1231,18 @@ pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
}
},
TyKind::Path(qpath) => self.hash_qpath(qpath),
TyKind::OpaqueDef(_, arg_list) => {
self.hash_generic_args(arg_list);
},
TyKind::TraitObject(_, lifetime, _) => {
self.hash_lifetime(lifetime);
},
TyKind::Typeof(anon_const) => {
self.hash_body(anon_const.body);
},
TyKind::Err(_) | TyKind::Infer | TyKind::Never | TyKind::InferDelegation(..) | TyKind::AnonAdt(_) => {},
TyKind::Err(_)
| TyKind::Infer
| TyKind::Never
| TyKind::InferDelegation(..)
| TyKind::OpaqueDef(_)
| TyKind::AnonAdt(_) => {},
}
}

View File

@ -1210,8 +1210,8 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
let capture = match capture.info.capture_kind {
UpvarCapture::ByValue => CaptureKind::Value,
UpvarCapture::ByRef(kind) => match kind {
BorrowKind::ImmBorrow => CaptureKind::Ref(Mutability::Not),
BorrowKind::UniqueImmBorrow | BorrowKind::MutBorrow => {
BorrowKind::Immutable => CaptureKind::Ref(Mutability::Not),
BorrowKind::UniqueImmutable | BorrowKind::Mutable => {
CaptureKind::Ref(Mutability::Mut)
},
},
@ -3338,8 +3338,8 @@ pub fn get_path_from_caller_to_method_type<'tcx>(
let assoc_item = tcx.associated_item(method);
let def_id = assoc_item.container_id(tcx);
match assoc_item.container {
rustc_ty::TraitContainer => get_path_to_callee(tcx, from, def_id),
rustc_ty::ImplContainer => {
rustc_ty::AssocItemContainer::Trait => get_path_to_callee(tcx, from, def_id),
rustc_ty::AssocItemContainer::Impl => {
let ty = tcx.type_of(def_id).instantiate_identity();
get_path_to_ty(tcx, from, ty, args)
},

View File

@ -185,9 +185,7 @@ pub fn new(cx: &LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
vis.into_map(cx)
};
let maybe_storage_live_result = MaybeStorageLive::new(Cow::Owned(BitSet::new_empty(mir.local_decls.len())))
.into_engine(cx.tcx, mir)
.pass_name("redundant_clone")
.iterate_to_fixpoint()
.iterate_to_fixpoint(cx.tcx, mir, Some("redundant_clone"))
.into_results_cursor(mir);
let mut vis = PossibleBorrowerVisitor::new(cx, mir, possible_origin);
vis.visit_body(mir);

View File

@ -334,7 +334,7 @@ fn check_terminator<'tcx>(
| TerminatorKind::TailCall { func, args, fn_span: _ } => {
let fn_ty = func.ty(body, tcx);
if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() {
if !is_const_fn(tcx, fn_def_id, msrv) {
if !is_stable_const_fn(tcx, fn_def_id, msrv) {
return Err((
span,
format!(
@ -377,12 +377,12 @@ fn check_terminator<'tcx>(
}
}
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
tcx.is_const_fn(def_id)
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
&& tcx.lookup_const_stability(def_id).is_none_or(|const_stab| {
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
// function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`.
// function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
let const_stab_rust_version = match since {
@ -393,14 +393,18 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
msrv.meets(const_stab_rust_version)
} else {
// Unstable const fn with the feature enabled.
msrv.current().is_none()
// Unstable const fn, check if the feature is enabled. We need both the regular stability
// feature and (if set) the const stability feature to const-call this function.
let stab = tcx.lookup_stability(def_id);
let is_enabled = stab.is_some_and(|s| s.is_stable() || tcx.features().enabled(s.feature))
&& const_stab.feature.is_none_or(|f| tcx.features().enabled(f));
is_enabled && msrv.current().is_none()
}
})
}
fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
// FIXME(effects, fee1-dead) revert to const destruct once it works again
// FIXME(const_trait_impl, fee1-dead) revert to const destruct once it works again
#[expect(unused)]
fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
// Avoid selecting for simple cases, such as builtin types.
@ -408,7 +412,7 @@ fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Bod
return true;
}
// FIXME(effects) constness
// FIXME(const_trait_impl) constness
let obligation = Obligation::new(
tcx,
ObligationCause::dummy_with_span(body.span),
@ -416,7 +420,7 @@ fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Bod
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
);
let infcx = tcx.infer_ctxt().build();
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
let mut selcx = SelectionContext::new(&infcx);
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
return false;

View File

@ -19,7 +19,7 @@
use rustc_middle::ty::{
self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind,
GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, UintTy, Upcast, VariantDef, VariantDiscr,
};
use rustc_span::symbol::Ident;
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@ -268,30 +268,13 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
return false;
}
let infcx = tcx.infer_ctxt().build();
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
let args = args
.into_iter()
.map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))
.collect::<Vec<_>>();
// If an effect arg was not specified, we need to specify it.
let effect_arg = if tcx
.generics_of(trait_id)
.host_effect_index
.is_some_and(|x| args.get(x - 1).is_none())
{
Some(GenericArg::from(callee_id.map_or(tcx.consts.true_, |def_id| {
tcx.expected_host_effect_param_for_body(def_id)
})))
} else {
None
};
let trait_ref = TraitRef::new(
tcx,
trait_id,
[GenericArg::from(ty)].into_iter().chain(args).chain(effect_arg),
);
let trait_ref = TraitRef::new(tcx, trait_id, [GenericArg::from(ty)].into_iter().chain(args));
debug_assert_matches!(
tcx.def_kind(trait_id),
@ -375,7 +358,7 @@ fn is_normalizable_helper<'tcx>(
}
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow
cache.insert(ty, false);
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let cause = ObligationCause::dummy();
let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
match ty.kind() {
@ -988,9 +971,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {
match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) {
(Ok(size), _) => size,
(Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(),
(Err(_), ty::Array(t, n)) => {
n.try_eval_target_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t)
},
(Err(_), ty::Array(t, n)) => n.try_to_target_usize(cx.tcx).unwrap_or_default() * approx_ty_size(cx, *t),
(Err(_), ty::Adt(def, subst)) if def.is_struct() => def
.variants()
.iter()
@ -1207,7 +1188,7 @@ pub fn interior_mut_ty_chain(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) ->
let chain = match *ty.kind() {
ty::RawPtr(inner_ty, _) if !self.ignore_pointers => self.interior_mut_ty_chain(cx, inner_ty),
ty::Ref(_, inner_ty, _) | ty::Slice(inner_ty) => self.interior_mut_ty_chain(cx, inner_ty),
ty::Array(inner_ty, size) if size.try_eval_target_usize(cx.tcx, cx.param_env) != Some(0) => {
ty::Array(inner_ty, size) if size.try_to_target_usize(cx.tcx) != Some(0) => {
self.interior_mut_ty_chain(cx, inner_ty)
},
ty::Tuple(fields) => fields.iter().find_map(|ty| self.interior_mut_ty_chain(cx, ty)),
@ -1281,7 +1262,7 @@ fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>)
let cause = ObligationCause::dummy();
match tcx
.infer_ctxt()
.build()
.build(TypingMode::from_param_env(param_env))
.at(&cause, param_env)
.query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args))
{
@ -1297,7 +1278,12 @@ fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>)
pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
let cause = ObligationCause::dummy();
match tcx.infer_ctxt().build().at(&cause, param_env).query_normalize(ty) {
match tcx
.infer_ctxt()
.build(TypingMode::from_param_env(param_env))
.at(&cause, param_env)
.query_normalize(ty)
{
Ok(ty) => ty.value,
Err(_) => ty,
}

View File

@ -207,16 +207,7 @@ fn path_segment_certainty(
if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
let generics = cx.tcx.generics_of(def_id);
let own_count = generics.own_params.len()
- usize::from(generics.host_effect_index.is_some_and(|index| {
// Check that the host index actually belongs to this resolution.
// E.g. for `Add::add`, host_effect_index is `Some(2)`, but it's part of the parent `Add`
// trait's generics.
// Add params: [Self#0, Rhs#1, host#2] parent_count=0, count=3
// Add::add params: [] parent_count=3, count=3
// (3..3).contains(&host_effect_index) => false
(generics.parent_count..generics.count()).contains(&index)
}));
let own_count = generics.own_params.len();
let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 {
Certainty::Certain(None)
} else {
@ -310,11 +301,10 @@ fn type_is_inferable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> bo
// Check that all type parameters appear in the functions input types.
(0..(generics.parent_count + generics.own_params.len()) as u32).all(|index| {
Some(index as usize) == generics.host_effect_index
|| fn_sig
.inputs()
.iter()
.any(|input_ty| contains_param(*input_ty.skip_binder(), index))
fn_sig
.inputs()
.iter()
.any(|input_ty| contains_param(*input_ty.skip_binder(), index))
})
}

View File

@ -67,7 +67,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) {
if bk == ty::BorrowKind::MutBorrow {
if bk == ty::BorrowKind::Mutable {
self.update(cmt);
}
}

View File

@ -344,13 +344,13 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {
.cx
.qpath_res(p, hir_id)
.opt_def_id()
.map_or(false, |id| self.cx.tcx.is_const_fn_raw(id)) => {},
.map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
ExprKind::MethodCall(..)
if self
.cx
.typeck_results()
.type_dependent_def_id(e.hir_id)
.map_or(false, |id| self.cx.tcx.is_const_fn_raw(id)) => {},
.map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
ExprKind::Binary(_, lhs, rhs)
if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()
&& self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},

View File

@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2024-10-18"
channel = "nightly-2024-11-07"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
profile = "minimal"

View File

@ -7,7 +7,7 @@
#[macro_use]
extern crate rustc_session;
extern crate rustc_lint;
use rustc_lint::LintPass;
use rustc_lint::{LintPass, LintVec};
declare_tool_lint! {
pub clippy::TEST_LINT,
@ -35,6 +35,9 @@ impl LintPass for Pass {
fn name(&self) -> &'static str {
"TEST_LINT"
}
fn get_lints(&self) -> LintVec {
vec![TEST_LINT]
}
}
declare_lint_pass!(Pass2 => [TEST_LINT_REGISTERED]);

View File

@ -19,13 +19,5 @@ error: #[allow] attribute found
LL | #[allow(unused)]
| ^^^^^ help: replace it with: `expect`
error: #[allow] attribute found
--> tests/ui/allow_attributes.rs:53:7
|
LL | #[allow(unused)]
| ^^^^^ help: replace it with: `expect`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View File

@ -43,14 +43,5 @@ LL | #[allow(unused)]
|
= help: try adding a reason at the end with `, reason = ".."`
error: `allow` attribute without specifying a reason
--> tests/ui/allow_attributes_without_reason.rs:46:5
|
LL | #[allow(unused)]
| ^^^^^^^^^^^^^^^^
|
= help: try adding a reason at the end with `, reason = ".."`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 6 previous errors
error: aborting due to 5 previous errors

View File

@ -1,12 +1,3 @@
error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea
--> tests/ui/attrs.rs:5:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::inline-always` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::inline_always)]`
error: the since field must contain a semver-compliant version
--> tests/ui/attrs.rs:27:14
|
@ -22,5 +13,14 @@ error: the since field must contain a semver-compliant version
LL | #[deprecated(since = "1")]
| ^^^^^^^^^^^
error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea
--> tests/ui/attrs.rs:5:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::inline-always` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::inline_always)]`
error: aborting due to 3 previous errors

View File

@ -1,3 +1,10 @@
error: `clippy::restriction` is not meant to be enabled as a group
|
= note: because of the command line `--warn clippy::restriction`
= help: enable the restriction lints you need individually
= note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]`
error: `clippy::restriction` is not meant to be enabled as a group
--> tests/ui/blanket_clippy_restriction_lints.rs:6:9
|
@ -5,8 +12,6 @@ LL | #![warn(clippy::restriction)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: enable the restriction lints you need individually
= note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]`
error: `clippy::restriction` is not meant to be enabled as a group
--> tests/ui/blanket_clippy_restriction_lints.rs:8:9
@ -24,10 +29,5 @@ LL | #![forbid(clippy::restriction)]
|
= help: enable the restriction lints you need individually
error: `clippy::restriction` is not meant to be enabled as a group
|
= note: because of the command line `--warn clippy::restriction`
= help: enable the restriction lints you need individually
error: aborting due to 4 previous errors

View File

@ -1,7 +1,6 @@
//@no-rustfix
#![feature(repr128)]
#![feature(isqrt)]
#![allow(incomplete_features)]
#![warn(
clippy::cast_precision_loss,

View File

@ -1,5 +1,5 @@
error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
--> tests/ui/cast.rs:26:5
--> tests/ui/cast.rs:25:5
|
LL | x0 as f32;
| ^^^^^^^^^
@ -8,37 +8,37 @@ LL | x0 as f32;
= help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`
error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
--> tests/ui/cast.rs:30:5
--> tests/ui/cast.rs:29:5
|
LL | x1 as f32;
| ^^^^^^^^^
error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
--> tests/ui/cast.rs:32:5
--> tests/ui/cast.rs:31:5
|
LL | x1 as f64;
| ^^^^^^^^^
error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
--> tests/ui/cast.rs:35:5
--> tests/ui/cast.rs:34:5
|
LL | x2 as f32;
| ^^^^^^^^^
error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
--> tests/ui/cast.rs:38:5
--> tests/ui/cast.rs:37:5
|
LL | x3 as f32;
| ^^^^^^^^^
error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
--> tests/ui/cast.rs:40:5
--> tests/ui/cast.rs:39:5
|
LL | x3 as f64;
| ^^^^^^^^^
error: casting `f32` to `i32` may truncate the value
--> tests/ui/cast.rs:43:5
--> tests/ui/cast.rs:42:5
|
LL | 1f32 as i32;
| ^^^^^^^^^^^
@ -48,7 +48,7 @@ LL | 1f32 as i32;
= help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
error: casting `f32` to `u32` may truncate the value
--> tests/ui/cast.rs:45:5
--> tests/ui/cast.rs:44:5
|
LL | 1f32 as u32;
| ^^^^^^^^^^^
@ -56,7 +56,7 @@ LL | 1f32 as u32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:45:5
--> tests/ui/cast.rs:44:5
|
LL | 1f32 as u32;
| ^^^^^^^^^^^
@ -65,7 +65,7 @@ LL | 1f32 as u32;
= help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]`
error: casting `f64` to `f32` may truncate the value
--> tests/ui/cast.rs:49:5
--> tests/ui/cast.rs:48:5
|
LL | 1f64 as f32;
| ^^^^^^^^^^^
@ -73,7 +73,7 @@ LL | 1f64 as f32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `i32` to `i8` may truncate the value
--> tests/ui/cast.rs:51:5
--> tests/ui/cast.rs:50:5
|
LL | 1i32 as i8;
| ^^^^^^^^^^
@ -85,7 +85,7 @@ LL | i8::try_from(1i32);
| ~~~~~~~~~~~~~~~~~~
error: casting `i32` to `u8` may truncate the value
--> tests/ui/cast.rs:53:5
--> tests/ui/cast.rs:52:5
|
LL | 1i32 as u8;
| ^^^^^^^^^^
@ -97,7 +97,7 @@ LL | u8::try_from(1i32);
| ~~~~~~~~~~~~~~~~~~
error: casting `f64` to `isize` may truncate the value
--> tests/ui/cast.rs:55:5
--> tests/ui/cast.rs:54:5
|
LL | 1f64 as isize;
| ^^^^^^^^^^^^^
@ -105,7 +105,7 @@ LL | 1f64 as isize;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f64` to `usize` may truncate the value
--> tests/ui/cast.rs:57:5
--> tests/ui/cast.rs:56:5
|
LL | 1f64 as usize;
| ^^^^^^^^^^^^^
@ -113,13 +113,13 @@ LL | 1f64 as usize;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f64` to `usize` may lose the sign of the value
--> tests/ui/cast.rs:57:5
--> tests/ui/cast.rs:56:5
|
LL | 1f64 as usize;
| ^^^^^^^^^^^^^
error: casting `u32` to `u16` may truncate the value
--> tests/ui/cast.rs:60:5
--> tests/ui/cast.rs:59:5
|
LL | 1f32 as u32 as u16;
| ^^^^^^^^^^^^^^^^^^
@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `f32` to `u32` may truncate the value
--> tests/ui/cast.rs:60:5
--> tests/ui/cast.rs:59:5
|
LL | 1f32 as u32 as u16;
| ^^^^^^^^^^^
@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:60:5
--> tests/ui/cast.rs:59:5
|
LL | 1f32 as u32 as u16;
| ^^^^^^^^^^^
error: casting `i32` to `i8` may truncate the value
--> tests/ui/cast.rs:65:22
--> tests/ui/cast.rs:64:22
|
LL | let _x: i8 = 1i32 as _;
| ^^^^^^^^^
@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into();
| ~~~~~~~~~~~~~~~
error: casting `f32` to `i32` may truncate the value
--> tests/ui/cast.rs:67:9
--> tests/ui/cast.rs:66:9
|
LL | 1f32 as i32;
| ^^^^^^^^^^^
@ -165,7 +165,7 @@ LL | 1f32 as i32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f64` to `i32` may truncate the value
--> tests/ui/cast.rs:69:9
--> tests/ui/cast.rs:68:9
|
LL | 1f64 as i32;
| ^^^^^^^^^^^
@ -173,7 +173,7 @@ LL | 1f64 as i32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u8` may truncate the value
--> tests/ui/cast.rs:71:9
--> tests/ui/cast.rs:70:9
|
LL | 1f32 as u8;
| ^^^^^^^^^^
@ -181,13 +181,13 @@ LL | 1f32 as u8;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u8` may lose the sign of the value
--> tests/ui/cast.rs:71:9
--> tests/ui/cast.rs:70:9
|
LL | 1f32 as u8;
| ^^^^^^^^^^
error: casting `u8` to `i8` may wrap around the value
--> tests/ui/cast.rs:76:5
--> tests/ui/cast.rs:75:5
|
LL | 1u8 as i8;
| ^^^^^^^^^
@ -196,31 +196,31 @@ LL | 1u8 as i8;
= help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`
error: casting `u16` to `i16` may wrap around the value
--> tests/ui/cast.rs:79:5
--> tests/ui/cast.rs:78:5
|
LL | 1u16 as i16;
| ^^^^^^^^^^^
error: casting `u32` to `i32` may wrap around the value
--> tests/ui/cast.rs:81:5
--> tests/ui/cast.rs:80:5
|
LL | 1u32 as i32;
| ^^^^^^^^^^^
error: casting `u64` to `i64` may wrap around the value
--> tests/ui/cast.rs:83:5
--> tests/ui/cast.rs:82:5
|
LL | 1u64 as i64;
| ^^^^^^^^^^^
error: casting `usize` to `isize` may wrap around the value
--> tests/ui/cast.rs:85:5
--> tests/ui/cast.rs:84:5
|
LL | 1usize as isize;
| ^^^^^^^^^^^^^^^
error: casting `usize` to `i8` may truncate the value
--> tests/ui/cast.rs:88:5
--> tests/ui/cast.rs:87:5
|
LL | 1usize as i8;
| ^^^^^^^^^^^^
@ -232,7 +232,7 @@ LL | i8::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i16` may truncate the value
--> tests/ui/cast.rs:91:5
--> tests/ui/cast.rs:90:5
|
LL | 1usize as i16;
| ^^^^^^^^^^^^^
@ -244,7 +244,7 @@ LL | i16::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers
--> tests/ui/cast.rs:91:5
--> tests/ui/cast.rs:90:5
|
LL | 1usize as i16;
| ^^^^^^^^^^^^^
@ -253,7 +253,7 @@ LL | 1usize as i16;
= note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
--> tests/ui/cast.rs:96:5
--> tests/ui/cast.rs:95:5
|
LL | 1usize as i32;
| ^^^^^^^^^^^^^
@ -265,19 +265,19 @@ LL | i32::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
--> tests/ui/cast.rs:96:5
--> tests/ui/cast.rs:95:5
|
LL | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers
--> tests/ui/cast.rs:100:5
--> tests/ui/cast.rs:99:5
|
LL | 1usize as i64;
| ^^^^^^^^^^^^^
error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers
--> tests/ui/cast.rs:105:5
--> tests/ui/cast.rs:104:5
|
LL | 1u16 as isize;
| ^^^^^^^^^^^^^
@ -286,13 +286,13 @@ LL | 1u16 as isize;
= note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
--> tests/ui/cast.rs:109:5
--> tests/ui/cast.rs:108:5
|
LL | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
--> tests/ui/cast.rs:112:5
--> tests/ui/cast.rs:111:5
|
LL | 1u64 as isize;
| ^^^^^^^^^^^^^
@ -304,55 +304,55 @@ LL | isize::try_from(1u64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
--> tests/ui/cast.rs:112:5
--> tests/ui/cast.rs:111:5
|
LL | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:117:5
--> tests/ui/cast.rs:116:5
|
LL | -1i32 as u32;
| ^^^^^^^^^^^^
error: casting `isize` to `usize` may lose the sign of the value
--> tests/ui/cast.rs:120:5
--> tests/ui/cast.rs:119:5
|
LL | -1isize as usize;
| ^^^^^^^^^^^^^^^^
error: casting `i8` to `u8` may lose the sign of the value
--> tests/ui/cast.rs:131:5
--> tests/ui/cast.rs:130:5
|
LL | (i8::MIN).abs() as u8;
| ^^^^^^^^^^^^^^^^^^^^^
error: casting `i64` to `u64` may lose the sign of the value
--> tests/ui/cast.rs:135:5
--> tests/ui/cast.rs:134:5
|
LL | (-1i64).abs() as u64;
| ^^^^^^^^^^^^^^^^^^^^
error: casting `isize` to `usize` may lose the sign of the value
--> tests/ui/cast.rs:136:5
--> tests/ui/cast.rs:135:5
|
LL | (-1isize).abs() as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i64` to `u64` may lose the sign of the value
--> tests/ui/cast.rs:143:5
--> tests/ui/cast.rs:142:5
|
LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i64` to `u64` may lose the sign of the value
--> tests/ui/cast.rs:158:5
--> tests/ui/cast.rs:157:5
|
LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i64` to `i8` may truncate the value
--> tests/ui/cast.rs:209:5
--> tests/ui/cast.rs:208:5
|
LL | (-99999999999i64).min(1) as i8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `u8` may truncate the value
--> tests/ui/cast.rs:223:5
--> tests/ui/cast.rs:222:5
|
LL | 999999u64.clamp(0, 256) as u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `main::E2` to `u8` may truncate the value
--> tests/ui/cast.rs:246:21
--> tests/ui/cast.rs:245:21
|
LL | let _ = self as u8;
| ^^^^^^^^^^
@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self);
| ~~~~~~~~~~~~~~~~~~
error: casting `main::E2::B` to `u8` will truncate the value
--> tests/ui/cast.rs:248:21
--> tests/ui/cast.rs:247:21
|
LL | let _ = Self::B as u8;
| ^^^^^^^^^^^^^
@ -397,7 +397,7 @@ LL | let _ = Self::B as u8;
= help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]`
error: casting `main::E5` to `i8` may truncate the value
--> tests/ui/cast.rs:290:21
--> tests/ui/cast.rs:289:21
|
LL | let _ = self as i8;
| ^^^^^^^^^^
@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self);
| ~~~~~~~~~~~~~~~~~~
error: casting `main::E5::A` to `i8` will truncate the value
--> tests/ui/cast.rs:292:21
--> tests/ui/cast.rs:291:21
|
LL | let _ = Self::A as i8;
| ^^^^^^^^^^^^^
error: casting `main::E6` to `i16` may truncate the value
--> tests/ui/cast.rs:309:21
--> tests/ui/cast.rs:308:21
|
LL | let _ = self as i16;
| ^^^^^^^^^^^
@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self);
| ~~~~~~~~~~~~~~~~~~~
error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
--> tests/ui/cast.rs:328:21
--> tests/ui/cast.rs:327:21
|
LL | let _ = self as usize;
| ^^^^^^^^^^^^^
@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `main::E10` to `u16` may truncate the value
--> tests/ui/cast.rs:375:21
--> tests/ui/cast.rs:374:21
|
LL | let _ = self as u16;
| ^^^^^^^^^^^
@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self);
| ~~~~~~~~~~~~~~~~~~~
error: casting `u32` to `u8` may truncate the value
--> tests/ui/cast.rs:386:13
--> tests/ui/cast.rs:385:13
|
LL | let c = (q >> 16) as u8;
| ^^^^^^^^^^^^^^^
@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u32` to `u8` may truncate the value
--> tests/ui/cast.rs:390:13
--> tests/ui/cast.rs:389:13
|
LL | let c = (q / 1000) as u8;
| ^^^^^^^^^^^^^^^^
@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000);
| ~~~~~~~~~~~~~~~~~~~~~~
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:402:9
--> tests/ui/cast.rs:401:9
|
LL | (x * x) as u32;
| ^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:407:32
--> tests/ui/cast.rs:406:32
|
LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 };
| ^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:409:5
--> tests/ui/cast.rs:408:5
|
LL | (2_i32).checked_pow(3).unwrap() as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:410:5
--> tests/ui/cast.rs:409:5
|
LL | (-2_i32).pow(3) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:415:5
--> tests/ui/cast.rs:414:5
|
LL | (-5_i32 % 2) as u32;
| ^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:417:5
--> tests/ui/cast.rs:416:5
|
LL | (-5_i32 % -2) as u32;
| ^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:420:5
--> tests/ui/cast.rs:419:5
|
LL | (-2_i32 >> 1) as u32;
| ^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:424:5
--> tests/ui/cast.rs:423:5
|
LL | (x * x) as u32;
| ^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:425:5
--> tests/ui/cast.rs:424:5
|
LL | (x * x * x) as u32;
| ^^^^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:429:5
--> tests/ui/cast.rs:428:5
|
LL | (y * y * y * y * -2) as u16;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:431:5
--> tests/ui/cast.rs:430:5
|
LL | (y * y * y / y * 2) as u16;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:432:5
--> tests/ui/cast.rs:431:5
|
LL | (y * y / y * 2) as u16;
| ^^^^^^^^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:434:5
--> tests/ui/cast.rs:433:5
|
LL | (y / y * y * -2) as u16;
| ^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `/`
--> tests/ui/cast.rs:434:6
--> tests/ui/cast.rs:433:6
|
LL | (y / y * y * -2) as u16;
| ^^^^^
@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16;
= note: `#[deny(clippy::eq_op)]` on by default
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:437:5
--> tests/ui/cast.rs:436:5
|
LL | (y + y + y + -2) as u16;
| ^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:439:5
--> tests/ui/cast.rs:438:5
|
LL | (y + y + y + 2) as u16;
| ^^^^^^^^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:443:5
--> tests/ui/cast.rs:442:5
|
LL | (z + -2) as u16;
| ^^^^^^^^^^^^^^^
error: casting `i16` to `u16` may lose the sign of the value
--> tests/ui/cast.rs:445:5
--> tests/ui/cast.rs:444:5
|
LL | (z + z + 2) as u16;
| ^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:448:9
--> tests/ui/cast.rs:447:9
|
LL | (a * a * b * b * c * c) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:449:9
--> tests/ui/cast.rs:448:9
|
LL | (a * b * c) as u32;
| ^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:451:9
--> tests/ui/cast.rs:450:9
|
LL | (a * -b * c) as u32;
| ^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:453:9
--> tests/ui/cast.rs:452:9
|
LL | (a * b * c * c) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:454:9
--> tests/ui/cast.rs:453:9
|
LL | (a * -2) as u32;
| ^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:456:9
--> tests/ui/cast.rs:455:9
|
LL | (a * b * c * -2) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:458:9
--> tests/ui/cast.rs:457:9
|
LL | (a / b) as u32;
| ^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:459:9
--> tests/ui/cast.rs:458:9
|
LL | (a / b * c) as u32;
| ^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:461:9
--> tests/ui/cast.rs:460:9
|
LL | (a / b + b * c) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:463:9
--> tests/ui/cast.rs:462:9
|
LL | a.saturating_pow(3) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:465:9
--> tests/ui/cast.rs:464:9
|
LL | (a.abs() * b.pow(2) / c.abs()) as u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
--> tests/ui/cast.rs:473:21
--> tests/ui/cast.rs:472:21
|
LL | let _ = i32::MIN as u32; // cast_sign_loss
| ^^^^^^^^^^^^^^^
@ -662,7 +662,7 @@ LL | m!();
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: casting `u32` to `u8` may truncate the value
--> tests/ui/cast.rs:474:21
--> tests/ui/cast.rs:473:21
|
LL | let _ = u32::MAX as u8; // cast_possible_truncation
| ^^^^^^^^^^^^^^
@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation
| ~~~~~~~~~~~~~~~~~~~~~~
error: casting `f64` to `f32` may truncate the value
--> tests/ui/cast.rs:475:21
--> tests/ui/cast.rs:474:21
|
LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -690,7 +690,7 @@ LL | m!();
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
--> tests/ui/cast.rs:484:5
--> tests/ui/cast.rs:483:5
|
LL | bar.unwrap().unwrap() as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap())
|
error: casting `i64` to `usize` may lose the sign of the value
--> tests/ui/cast.rs:484:5
--> tests/ui/cast.rs:483:5
|
LL | bar.unwrap().unwrap() as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting `u64` to `u8` may truncate the value
--> tests/ui/cast.rs:499:5
--> tests/ui/cast.rs:498:5
|
LL | (256 & 999999u64) as u8;
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `u8` may truncate the value
--> tests/ui/cast.rs:501:5
--> tests/ui/cast.rs:500:5
|
LL | (255 % 999999u64) as u8;
| ^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -11,7 +11,7 @@ error: the following explicit lifetimes could be elided: 'a
--> tests/ui/issue_4266.rs:10:21
|
LL | async fn one_to_one<'a>(s: &'a str) -> &'a str {
| ^^ ^^
| ^^ ^^ ^^
error: methods called `new` usually take no `self`
--> tests/ui/issue_4266.rs:31:22

View File

@ -1,7 +1,6 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
#![allow(unsupported_calling_conventions)]
#![feature(const_trait_impl)]
#![feature(const_trait_impl, abi_vectorcall)]
use std::mem::transmute;
@ -104,7 +103,7 @@ fn main() {}
struct D;
/* FIXME(effects)
/* FIXME(const_trait_impl)
impl const Drop for D {
fn drop(&mut self) {
todo!();
@ -113,7 +112,7 @@ impl const Drop for D {
*/
// Lint this, since it can be dropped in const contexts
// FIXME(effects)
// FIXME(const_trait_impl)
const fn d(this: D) {}
//~^ ERROR: this could be a `const fn`
@ -212,8 +211,8 @@ mod extern_fn {
//~^ ERROR: this could be a `const fn`
const extern "system-unwind" fn system_unwind() {}
//~^ ERROR: this could be a `const fn`
pub const extern "stdcall" fn std_call() {}
pub const extern "vectorcall" fn std_call() {}
//~^ ERROR: this could be a `const fn`
pub const extern "stdcall-unwind" fn std_call_unwind() {}
pub const extern "vectorcall-unwind" fn std_call_unwind() {}
//~^ ERROR: this could be a `const fn`
}

View File

@ -1,7 +1,6 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
#![allow(unsupported_calling_conventions)]
#![feature(const_trait_impl)]
#![feature(const_trait_impl, abi_vectorcall)]
use std::mem::transmute;
@ -104,7 +103,7 @@ fn main() {}
struct D;
/* FIXME(effects)
/* FIXME(const_trait_impl)
impl const Drop for D {
fn drop(&mut self) {
todo!();
@ -113,7 +112,7 @@ fn drop(&mut self) {
*/
// Lint this, since it can be dropped in const contexts
// FIXME(effects)
// FIXME(const_trait_impl)
fn d(this: D) {}
//~^ ERROR: this could be a `const fn`
@ -212,8 +211,8 @@ extern "system" fn system() {}
//~^ ERROR: this could be a `const fn`
extern "system-unwind" fn system_unwind() {}
//~^ ERROR: this could be a `const fn`
pub extern "stdcall" fn std_call() {}
pub extern "vectorcall" fn std_call() {}
//~^ ERROR: this could be a `const fn`
pub extern "stdcall-unwind" fn std_call_unwind() {}
pub extern "vectorcall-unwind" fn std_call_unwind() {}
//~^ ERROR: this could be a `const fn`
}

View File

@ -1,5 +1,5 @@
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:14:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:13:5
|
LL | / pub fn new() -> Self {
LL | |
@ -16,7 +16,7 @@ LL | pub const fn new() -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:20:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:19:5
|
LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
LL | |
@ -30,7 +30,7 @@ LL | const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T;
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:27:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:26:1
|
LL | / fn one() -> i32 {
LL | |
@ -44,7 +44,7 @@ LL | const fn one() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:33:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:32:1
|
LL | / fn two() -> i32 {
LL | |
@ -59,7 +59,7 @@ LL | const fn two() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:40:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:39:1
|
LL | / fn string() -> String {
LL | |
@ -73,7 +73,7 @@ LL | const fn string() -> String {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:46:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:45:1
|
LL | / unsafe fn four() -> i32 {
LL | |
@ -87,7 +87,7 @@ LL | const unsafe fn four() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:52:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:51:1
|
LL | / fn generic<T>(t: T) -> T {
LL | |
@ -101,7 +101,7 @@ LL | const fn generic<T>(t: T) -> T {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:61:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:60:1
|
LL | / fn generic_arr<T: Copy>(t: [T; 1]) -> T {
LL | |
@ -115,7 +115,7 @@ LL | const fn generic_arr<T: Copy>(t: [T; 1]) -> T {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:75:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:74:9
|
LL | / pub fn b(self, a: &A) -> B {
LL | |
@ -129,7 +129,7 @@ LL | pub const fn b(self, a: &A) -> B {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:85:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:84:5
|
LL | / fn const_fn_stabilized_before_msrv(byte: u8) {
LL | |
@ -143,7 +143,7 @@ LL | const fn const_fn_stabilized_before_msrv(byte: u8) {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:97:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:96:1
|
LL | / fn msrv_1_46() -> i32 {
LL | |
@ -157,7 +157,7 @@ LL | const fn msrv_1_46() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:117:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:116:1
|
LL | fn d(this: D) {}
| ^^^^^^^^^^^^^^^^
@ -168,7 +168,7 @@ LL | const fn d(this: D) {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:125:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:124:9
|
LL | / fn deref_ptr_can_be_const(self) -> usize {
LL | |
@ -182,7 +182,7 @@ LL | const fn deref_ptr_can_be_const(self) -> usize {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:130:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:129:9
|
LL | / fn deref_copied_val(self) -> usize {
LL | |
@ -196,7 +196,7 @@ LL | const fn deref_copied_val(self) -> usize {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:141:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:140:5
|
LL | / fn union_access_can_be_const() {
LL | |
@ -211,7 +211,7 @@ LL | const fn union_access_can_be_const() {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:149:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:148:9
|
LL | extern "C" fn c() {}
| ^^^^^^^^^^^^^^^^^^^^
@ -222,7 +222,7 @@ LL | const extern "C" fn c() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:153:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:152:9
|
LL | extern fn implicit_c() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@ -233,7 +233,7 @@ LL | const extern fn implicit_c() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:170:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:169:9
|
LL | / pub fn new(strings: Vec<String>) -> Self {
LL | | Self { strings }
@ -246,7 +246,7 @@ LL | pub const fn new(strings: Vec<String>) -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:175:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:174:9
|
LL | / pub fn empty() -> Self {
LL | | Self { strings: Vec::new() }
@ -259,7 +259,7 @@ LL | pub const fn empty() -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:186:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:185:9
|
LL | / pub fn new(text: String) -> Self {
LL | | let vec = Vec::new();
@ -273,7 +273,7 @@ LL | pub const fn new(text: String) -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:205:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:204:5
|
LL | fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -284,7 +284,7 @@ LL | const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:209:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:208:5
|
LL | extern "C-unwind" fn c_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -295,7 +295,7 @@ LL | const extern "C-unwind" fn c_unwind() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:211:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:210:5
|
LL | extern "system" fn system() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -306,7 +306,7 @@ LL | const extern "system" fn system() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:213:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:212:5
|
LL | extern "system-unwind" fn system_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -317,25 +317,25 @@ LL | const extern "system-unwind" fn system_unwind() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:215:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:214:5
|
LL | pub extern "stdcall" fn std_call() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | pub extern "vectorcall" fn std_call() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `const`
|
LL | pub const extern "stdcall" fn std_call() {}
LL | pub const extern "vectorcall" fn std_call() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:217:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:216:5
|
LL | pub extern "stdcall-unwind" fn std_call_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | pub extern "vectorcall-unwind" fn std_call_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `const`
|
LL | pub const extern "stdcall-unwind" fn std_call_unwind() {}
LL | pub const extern "vectorcall-unwind" fn std_call_unwind() {}
| +++++
error: aborting due to 26 previous errors

View File

@ -54,7 +54,7 @@
#![allow(enum_intrinsics_non_enums)]
#![allow(non_fmt_panics)]
#![allow(named_arguments_used_positionally)]
#![allow(temporary_cstring_as_ptr)]
#![allow(dangling_pointers_from_temporaries)]
#![allow(undropped_manually_drops)]
#![allow(unknown_lints)]
#![allow(unused_labels)]
@ -120,7 +120,7 @@
#![warn(unexpected_cfgs)] //~ ERROR: lint `clippy::mismatched_target_os`
#![warn(non_fmt_panics)] //~ ERROR: lint `clippy::panic_params`
#![warn(named_arguments_used_positionally)] //~ ERROR: lint `clippy::positional_named_format_parameters`
#![warn(temporary_cstring_as_ptr)] //~ ERROR: lint `clippy::temporary_cstring_as_ptr`
#![warn(dangling_pointers_from_temporaries)] //~ ERROR: lint `clippy::temporary_cstring_as_ptr`
#![warn(undropped_manually_drops)] //~ ERROR: lint `clippy::undropped_manually_drops`
#![warn(unknown_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints`
#![warn(unused_labels)] //~ ERROR: lint `clippy::unused_label`

View File

@ -54,7 +54,7 @@
#![allow(enum_intrinsics_non_enums)]
#![allow(non_fmt_panics)]
#![allow(named_arguments_used_positionally)]
#![allow(temporary_cstring_as_ptr)]
#![allow(dangling_pointers_from_temporaries)]
#![allow(undropped_manually_drops)]
#![allow(unknown_lints)]
#![allow(unused_labels)]

View File

@ -361,11 +361,11 @@ error: lint `clippy::positional_named_format_parameters` has been renamed to `na
LL | #![warn(clippy::positional_named_format_parameters)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
--> tests/ui/rename.rs:123:9
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
--> tests/ui/rename.rs:124:9