Auto merge of #101577 - Dylan-DPC:rollup-l9xw7i7, r=Dylan-DPC

Rollup of 7 pull requests

Successful merges:

 - #98933 (Opaque types' generic params do not imply anything about their hidden type's lifetimes)
 - #101041 (translations(rustc_session): migrates rustc_session to use SessionDiagnostic - Pt. 2)
 - #101424 (Adjust and slightly generalize operator error suggestion)
 - #101496 (Allow lower_lifetime_binder receive a closure)
 - #101501 (Allow lint passes to be bound by `TyCtxt`)
 - #101515 (Recover from typo where == is used in place of =)
 - #101545 (Remove unnecessary `PartialOrd` and `Ord`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-09-08 15:53:14 +00:00
commit 87788097b7
59 changed files with 1036 additions and 660 deletions

View File

@ -849,21 +849,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
(body_id, generator_option)
});
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
// Lower outside new scope to preserve `is_in_loop_condition`.
let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
self.lower_lifetime_binder(closure_id, generic_params, |lctx, bound_generic_params| {
// Lower outside new scope to preserve `is_in_loop_condition`.
let fn_decl = lctx.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
let c = self.arena.alloc(hir::Closure {
binder: binder_clause,
capture_clause,
bound_generic_params,
fn_decl,
body: body_id,
fn_decl_span: self.lower_span(fn_decl_span),
movability: generator_option,
});
let c = lctx.arena.alloc(hir::Closure {
binder: binder_clause,
capture_clause,
bound_generic_params,
fn_decl,
body: body_id,
fn_decl_span: lctx.lower_span(fn_decl_span),
movability: generator_option,
});
hir::ExprKind::Closure(c)
hir::ExprKind::Closure(c)
})
}
fn generator_movability_for_fn(
@ -950,23 +951,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
body_id
});
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
self.lower_lifetime_binder(closure_id, generic_params, |lctx, bound_generic_params| {
// We need to lower the declaration outside the new scope, because we
// have to conserve the state of being inside a loop condition for the
// closure argument types.
let fn_decl = lctx.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
// We need to lower the declaration outside the new scope, because we
// have to conserve the state of being inside a loop condition for the
// closure argument types.
let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
let c = self.arena.alloc(hir::Closure {
binder: binder_clause,
capture_clause,
bound_generic_params,
fn_decl,
body,
fn_decl_span: self.lower_span(fn_decl_span),
movability: None,
});
hir::ExprKind::Closure(c)
let c = lctx.arena.alloc(hir::Closure {
binder: binder_clause,
capture_clause,
bound_generic_params,
fn_decl,
body,
fn_decl_span: lctx.lower_span(fn_decl_span),
movability: None,
});
hir::ExprKind::Closure(c)
})
}
/// Destructure the LHS of complex assignments.

View File

@ -810,23 +810,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
/// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
/// parameters will be successful.
#[instrument(level = "debug", skip(self))]
#[instrument(level = "debug", skip(self, in_binder))]
#[inline]
fn lower_lifetime_binder(
fn lower_lifetime_binder<R>(
&mut self,
binder: NodeId,
generic_params: &[GenericParam],
) -> &'hir [hir::GenericParam<'hir>] {
let mut generic_params: Vec<_> = self.lower_generic_params_mut(generic_params).collect();
in_binder: impl FnOnce(&mut Self, &'hir [hir::GenericParam<'hir>]) -> R,
) -> R {
let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder);
debug!(?extra_lifetimes);
generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
self.lifetime_res_to_generic_param(ident, node_id, res)
}));
let extra_lifetimes: Vec<_> = extra_lifetimes
.into_iter()
.filter_map(|(ident, node_id, res)| {
self.lifetime_res_to_generic_param(ident, node_id, res)
})
.collect();
let generic_params: Vec<_> = self
.lower_generic_params_mut(generic_params)
.chain(extra_lifetimes.into_iter())
.collect();
let generic_params = self.arena.alloc_from_iter(generic_params);
debug!(?generic_params);
generic_params
in_binder(self, generic_params)
}
fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
@ -1236,14 +1244,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
}
TyKind::BareFn(ref f) => {
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
generic_params,
unsafety: self.lower_unsafety(f.unsafety),
abi: self.lower_extern(f.ext),
decl: self.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
param_names: self.lower_fn_params_to_names(&f.decl),
}))
self.lower_lifetime_binder(t.id, &f.generic_params, |lctx, generic_params| {
hir::TyKind::BareFn(lctx.arena.alloc(hir::BareFnTy {
generic_params,
unsafety: lctx.lower_unsafety(f.unsafety),
abi: lctx.lower_extern(f.ext),
decl: lctx.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
param_names: lctx.lower_fn_params_to_names(&f.decl),
}))
})
}
TyKind::Never => hir::TyKind::Never,
TyKind::Tup(ref tys) => hir::TyKind::Tup(
@ -2143,10 +2152,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
p: &PolyTraitRef,
itctx: &mut ImplTraitContext,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx);
hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
self.lower_lifetime_binder(
p.trait_ref.ref_id,
&p.bound_generic_params,
|lctx, bound_generic_params| {
let trait_ref = lctx.lower_trait_ref(&p.trait_ref, itctx);
hir::PolyTraitRef { bound_generic_params, trait_ref, span: lctx.lower_span(p.span) }
},
)
}
fn lower_mt(&mut self, mt: &MutTy, itctx: &mut ImplTraitContext) -> hir::MutTy<'hir> {

View File

@ -135,7 +135,6 @@ pub struct RegionInferenceContext<'tcx> {
/// adds a new lower bound to the SCC it is analyzing: so you wind up
/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
/// minimal viable option.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub(crate) struct AppliedMemberConstraint {
/// The SCC that was affected. (The "member region".)
///

View File

@ -153,3 +153,6 @@ parser_left_arrow_operator = unexpected token: `<-`
parser_remove_let = expected pattern, found `let`
.suggestion = remove the unnecessary `let` keyword
parser_use_eq_instead = unexpected `==`
.suggestion = try using `=` instead

View File

@ -14,3 +14,45 @@ session_feature_diagnostic_for_issue =
session_feature_diagnostic_help =
add `#![feature({$feature})]` to the crate attributes to enable
session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist.
session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`
session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
session_sanitizers_not_supported = {$us} sanitizers are not supported for this target
session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`
session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
session_sanitizer_cfi_enabled = `-Zsanitizer=cfi` requires `-Clto`
session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto`
session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is greater than 5
session_target_invalid_address_space = invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
session_target_invalid_bits = invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
session_target_missing_alignment = missing alignment for `{$cause}` in "data-layout"
session_target_invalid_alignment = invalid alignment for `{$cause}` in "data-layout": {$err}
session_target_inconsistent_architecture = inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
session_target_inconsistent_pointer_width = inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
session_target_invalid_bits_size = {$err}
session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored
session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform

View File

@ -10,10 +10,11 @@ use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_span::edition::LATEST_STABLE_EDITION;
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
use rustc_span::{edition::Edition, Span, DUMMY_SP};
use rustc_target::spec::PanicStrategy;
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
use std::borrow::Cow;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
/// Error type for `Diagnostic`'s `suggestions` field, indicating that
@ -91,6 +92,10 @@ into_diagnostic_arg_using_display!(
Edition,
Ident,
MacroRulesNormalizedIdent,
ParseIntError,
StackProtector,
&TargetTriple,
SplitDebuginfo
);
impl IntoDiagnosticArg for bool {

View File

@ -456,7 +456,7 @@ struct HandlerInner {
}
/// A key denoting where from a diagnostic was stashed.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum StashKey {
ItemNoType,
UnderscoreForArrayLengths,

View File

@ -457,7 +457,7 @@ impl PartialRes {
/// Different kinds of symbols can coexist even if they share the same textual name.
/// Therefore, they each have a separate universe (known as a "namespace").
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Namespace {
/// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
/// (and, by extension, crates).

View File

@ -141,7 +141,7 @@ pub enum TokenKind {
Unknown,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DocStyle {
Outer,
Inner,

View File

@ -50,6 +50,10 @@ use std::cell::Cell;
use std::iter;
use std::slice;
type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync;
type LateLintPassFactory =
dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::Send + sync::Sync;
/// Information about the registered lints.
///
/// This is basically the subset of `Context` that we can
@ -64,11 +68,11 @@ pub struct LintStore {
/// interior mutability, we don't enforce this (and lints should, in theory,
/// be compatible with being constructed more than once, though not
/// necessarily in a sane manner. This is safe though.)
pub pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
pub early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
pub late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
pub pre_expansion_passes: Vec<Box<EarlyLintPassFactory>>,
pub early_passes: Vec<Box<EarlyLintPassFactory>>,
pub late_passes: Vec<Box<LateLintPassFactory>>,
/// This is unique in that we construct them per-module, so not once.
pub late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
pub late_module_passes: Vec<Box<LateLintPassFactory>>,
/// Lints indexed by name.
by_name: FxHashMap<String, TargetLint>,
@ -186,14 +190,20 @@ impl LintStore {
pub fn register_late_pass(
&mut self,
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
+ 'static
+ sync::Send
+ sync::Sync,
) {
self.late_passes.push(Box::new(pass));
}
pub fn register_late_mod_pass(
&mut self,
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
+ 'static
+ sync::Send
+ sync::Sync,
) {
self.late_module_passes.push(Box::new(pass));
}
@ -558,7 +568,7 @@ pub trait LintPassObject: Sized {}
impl LintPassObject for EarlyLintPassObject {}
impl LintPassObject for LateLintPassObject {}
impl LintPassObject for LateLintPassObject<'_> {}
pub trait LintContext: Sized {
type PassObject: LintPassObject;
@ -949,8 +959,8 @@ impl<'a> EarlyContext<'a> {
}
}
impl LintContext for LateContext<'_> {
type PassObject = LateLintPassObject;
impl<'tcx> LintContext for LateContext<'tcx> {
type PassObject = LateLintPassObject<'tcx>;
/// Gets the overall compiler `Session` object.
fn sess(&self) -> &Session {

View File

@ -306,12 +306,12 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
}
struct LateLintPassObjects<'a> {
lints: &'a mut [LateLintPassObject],
struct LateLintPassObjects<'a, 'tcx> {
lints: &'a mut [LateLintPassObject<'tcx>],
}
#[allow(rustc::lint_pass_impl_without_macro)]
impl LintPass for LateLintPassObjects<'_> {
impl LintPass for LateLintPassObjects<'_, '_> {
fn name(&self) -> &'static str {
panic!()
}
@ -329,7 +329,7 @@ macro_rules! expand_late_lint_pass_impl_methods {
macro_rules! late_lint_pass_impl {
([], [$hir:tt], $methods:tt) => {
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_> {
impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
expand_late_lint_pass_impl_methods!([$hir], $methods);
}
};
@ -382,7 +382,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
late_lint_mod_pass(tcx, module_def_id, builtin_lints);
let mut passes: Vec<_> =
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
if !passes.is_empty() {
late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
@ -418,7 +418,8 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
}
fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
let mut passes = unerased_lint_store(tcx).late_passes.iter().map(|p| (p)()).collect::<Vec<_>>();
let mut passes =
unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
if !tcx.sess.opts.unstable_opts.no_interleave_lints {
if !passes.is_empty() {
@ -434,7 +435,7 @@ fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints
}
let mut passes: Vec<_> =
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)()).collect();
unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
for pass in &mut passes {
tcx.sess.prof.extra_verbose_generic_activity("run_late_module_lint", pass.name()).run(

View File

@ -260,26 +260,41 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
)
}
macro_rules! register_pass {
macro_rules! register_early_pass {
($method:ident, $ty:ident, $constructor:expr) => {
store.register_lints(&$ty::get_lints());
store.$method(|| Box::new($constructor));
};
}
macro_rules! register_passes {
macro_rules! register_late_pass {
($method:ident, $ty:ident, $constructor:expr) => {
store.register_lints(&$ty::get_lints());
store.$method(|_| Box::new($constructor));
};
}
macro_rules! register_early_passes {
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
$(
register_pass!($method, $passes, $constructor);
register_early_pass!($method, $passes, $constructor);
)*
)
}
macro_rules! register_late_passes {
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
$(
register_late_pass!($method, $passes, $constructor);
)*
)
}
if no_interleave_lints {
pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
early_lint_passes!(register_passes, register_early_pass);
late_lint_passes!(register_passes, register_late_pass);
late_lint_mod_passes!(register_passes, register_late_mod_pass);
pre_expansion_lint_passes!(register_early_passes, register_pre_expansion_pass);
early_lint_passes!(register_early_passes, register_early_pass);
late_lint_passes!(register_late_passes, register_late_pass);
late_lint_mod_passes!(register_late_passes, register_late_mod_pass);
} else {
store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
@ -510,19 +525,19 @@ fn register_internals(store: &mut LintStore) {
store.register_lints(&LintPassImpl::get_lints());
store.register_early_pass(|| Box::new(LintPassImpl));
store.register_lints(&DefaultHashTypes::get_lints());
store.register_late_pass(|| Box::new(DefaultHashTypes));
store.register_late_pass(|_| Box::new(DefaultHashTypes));
store.register_lints(&QueryStability::get_lints());
store.register_late_pass(|| Box::new(QueryStability));
store.register_late_pass(|_| Box::new(QueryStability));
store.register_lints(&ExistingDocKeyword::get_lints());
store.register_late_pass(|| Box::new(ExistingDocKeyword));
store.register_late_pass(|_| Box::new(ExistingDocKeyword));
store.register_lints(&TyTyKind::get_lints());
store.register_late_pass(|| Box::new(TyTyKind));
store.register_late_pass(|_| Box::new(TyTyKind));
store.register_lints(&Diagnostics::get_lints());
store.register_late_pass(|| Box::new(Diagnostics));
store.register_late_pass(|_| Box::new(Diagnostics));
store.register_lints(&BadOptAccess::get_lints());
store.register_late_pass(|| Box::new(BadOptAccess));
store.register_late_pass(|_| Box::new(BadOptAccess));
store.register_lints(&PassByValue::get_lints());
store.register_late_pass(|| Box::new(PassByValue));
store.register_late_pass(|_| Box::new(PassByValue));
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
// these lints will trigger all of the time - change this once migration to diagnostic structs

View File

@ -244,4 +244,4 @@ macro_rules! declare_combined_early_lint_pass {
/// A lint pass boxed up as a trait object.
pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + 'static>;
pub type LateLintPassObject = Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + 'static>;
pub type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + sync::Send + 'tcx>;

View File

@ -741,7 +741,7 @@ pub enum TerminatorKind<'tcx> {
}
/// Information about an assertion failure.
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, PartialOrd)]
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
pub enum AssertKind<O> {
BoundsCheck { len: O, index: O },
Overflow(BinOp, O, O),

View File

@ -14,7 +14,7 @@ use std::slice;
pub use super::query::*;
#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, PartialOrd)]
#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
pub struct SwitchTargets {
/// Possible values. The locations to branch to in each case
/// are found in the corresponding indices from the `targets` vector.

View File

@ -12,7 +12,7 @@ pub mod util;
use crate::infer::canonical::Canonical;
use crate::ty::abstract_const::NotConstEvaluatable;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, AdtKind, Predicate, Ty, TyCtxt};
use crate::ty::{self, AdtKind, Ty, TyCtxt};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, Diagnostic};
@ -416,7 +416,7 @@ pub enum ObligationCauseCode<'tcx> {
BinOp {
rhs_span: Option<Span>,
is_lit: bool,
output_pred: Option<Predicate<'tcx>>,
output_ty: Option<Ty<'tcx>>,
},
}

View File

@ -1252,7 +1252,7 @@ impl<'tcx> TyCtxt<'tcx> {
output_filenames: OutputFilenames,
) -> GlobalCtxt<'tcx> {
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
s.fatal(&err);
s.emit_fatal(err);
});
let interners = CtxtInterners::new(arena);
let common_types = CommonTypes::new(

View File

@ -102,13 +102,25 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
generics: &hir::Generics<'_>,
err: &mut Diagnostic,
trait_pred: PolyTraitPredicate<'tcx>,
associated_ty: Option<(&'static str, Ty<'tcx>)>,
) -> bool {
if !trait_pred.is_suggestable(tcx, false) {
return false;
}
let param_name = trait_pred.skip_binder().self_ty().to_string();
let constraint = trait_pred.print_modifiers_and_trait_path().to_string();
let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string();
if let Some((name, term)) = associated_ty {
// FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
// That should be extracted into a helper function.
if constraint.ends_with('>') {
constraint = format!("{}, {} = {}>", &constraint[..constraint.len() - 1], name, term);
} else {
constraint.push_str(&format!("<{} = {}>", name, term));
}
}
let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
// Skip, there is a param named Self

View File

@ -666,7 +666,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
// ignore the inputs to a projection, as they may not appear
// in the normalized form
if self.just_constrained {
if let ty::Projection(..) = t.kind() {
if let ty::Projection(..) | ty::Opaque(..) = t.kind() {
return ControlFlow::CONTINUE;
}
}

View File

@ -713,6 +713,14 @@ pub(crate) struct RemoveLet {
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[diag(parser::use_eq_instead)]
pub(crate) struct UseEqInstead {
#[primary_span]
#[suggestion_short(applicability = "machine-applicable", code = "=")]
pub span: Span,
}
// SnapshotParser is used to create a snapshot of the parser
// without causing duplicate errors being emitted when the `Parser`
// is dropped.
@ -957,6 +965,14 @@ impl<'a> Parser<'a> {
}
}
if self.token.kind == TokenKind::EqEq
&& self.prev_token.is_ident()
&& expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq)))
{
// Likely typo: `=` → `==` in let expr or enum item
return Err(self.sess.create_err(UseEqInstead { span: self.token.span }));
}
let expect = tokens_to_string(&expected);
let actual = super::token_descr(&self.token);
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {

View File

@ -57,7 +57,7 @@ use rustc_span::{Span, DUMMY_SP};
use smallvec::{smallvec, SmallVec};
use std::cell::{Cell, RefCell};
use std::collections::BTreeSet;
use std::{cmp, fmt, ptr};
use std::{fmt, ptr};
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
use imports::{Import, ImportKind, ImportResolver, NameResolution};
@ -163,7 +163,6 @@ enum ImplTraitContext {
Universal(LocalDefId),
}
#[derive(Eq)]
struct BindingError {
name: Symbol,
origin: BTreeSet<Span>,
@ -171,24 +170,6 @@ struct BindingError {
could_be_path: bool,
}
impl PartialOrd for BindingError {
fn partial_cmp(&self, other: &BindingError) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for BindingError {
fn eq(&self, other: &BindingError) -> bool {
self.name == other.name
}
}
impl Ord for BindingError {
fn cmp(&self, other: &BindingError) -> cmp::Ordering {
self.name.cmp(&other.name)
}
}
enum ResolutionError<'a> {
/// Error E0401: can't use type or const parameters from outer function.
GenericParamsFromOuterFunction(Res, HasGenericParams),
@ -845,7 +826,7 @@ impl<'a> NameBinding<'a> {
}
}
#[derive(Debug, Default, Clone)]
#[derive(Default, Clone)]
pub struct ExternPreludeEntry<'a> {
extern_crate_item: Option<&'a NameBinding<'a>>,
pub introduced_by_item: bool,

View File

@ -898,7 +898,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
let max_atomic_width = sess.target.max_atomic_width();
let atomic_cas = sess.target.atomic_cas;
let layout = TargetDataLayout::parse(&sess.target).unwrap_or_else(|err| {
sess.fatal(&err);
sess.emit_fatal(err);
});
let mut ret = CrateConfig::default();

View File

@ -1,10 +1,12 @@
use std::num::NonZeroU32;
use crate as rustc_session;
use crate::cgu_reuse_tracker::CguReuse;
use rustc_errors::MultiSpan;
use crate::{self as rustc_session, SessionDiagnostic};
use rustc_errors::{fluent, DiagnosticBuilder, Handler, MultiSpan};
use rustc_macros::SessionDiagnostic;
use rustc_span::{Span, Symbol};
use rustc_target::abi::TargetDataLayoutErrors;
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
#[derive(SessionDiagnostic)]
#[diag(session::incorrect_cgu_reuse_type)]
@ -43,3 +45,128 @@ pub struct FeatureDiagnosticForIssue {
pub struct FeatureDiagnosticHelp {
pub feature: Symbol,
}
impl SessionDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
fn into_diagnostic(self, sess: &Handler) -> DiagnosticBuilder<'_, !> {
let mut diag;
match self {
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
diag = sess.struct_fatal(fluent::session::target_invalid_address_space);
diag.set_arg("addr_space", addr_space);
diag.set_arg("cause", cause);
diag.set_arg("err", err);
diag
}
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
diag = sess.struct_fatal(fluent::session::target_invalid_bits);
diag.set_arg("kind", kind);
diag.set_arg("bit", bit);
diag.set_arg("cause", cause);
diag.set_arg("err", err);
diag
}
TargetDataLayoutErrors::MissingAlignment { cause } => {
diag = sess.struct_fatal(fluent::session::target_missing_alignment);
diag.set_arg("cause", cause);
diag
}
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
diag = sess.struct_fatal(fluent::session::target_invalid_alignment);
diag.set_arg("cause", cause);
diag.set_arg("err", err);
diag
}
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
diag = sess.struct_fatal(fluent::session::target_inconsistent_architecture);
diag.set_arg("dl", dl);
diag.set_arg("target", target);
diag
}
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
diag = sess.struct_fatal(fluent::session::target_inconsistent_pointer_width);
diag.set_arg("pointer_size", pointer_size);
diag.set_arg("target", target);
diag
}
TargetDataLayoutErrors::InvalidBitsSize { err } => {
diag = sess.struct_fatal(fluent::session::target_invalid_bits_size);
diag.set_arg("err", err);
diag
}
}
}
}
#[derive(SessionDiagnostic)]
#[diag(session::not_circumvent_feature)]
pub struct NotCircumventFeature;
#[derive(SessionDiagnostic)]
#[diag(session::linker_plugin_lto_windows_not_supported)]
pub struct LinkerPluginToWindowsNotSupported;
#[derive(SessionDiagnostic)]
#[diag(session::profile_use_file_does_not_exist)]
pub struct ProfileUseFileDoesNotExist<'a> {
pub path: &'a std::path::Path,
}
#[derive(SessionDiagnostic)]
#[diag(session::profile_sample_use_file_does_not_exist)]
pub struct ProfileSampleUseFileDoesNotExist<'a> {
pub path: &'a std::path::Path,
}
#[derive(SessionDiagnostic)]
#[diag(session::target_requires_unwind_tables)]
pub struct TargetRequiresUnwindTables;
#[derive(SessionDiagnostic)]
#[diag(session::sanitizer_not_supported)]
pub struct SanitizerNotSupported {
pub us: String,
}
#[derive(SessionDiagnostic)]
#[diag(session::sanitizers_not_supported)]
pub struct SanitizersNotSupported {
pub us: String,
}
#[derive(SessionDiagnostic)]
#[diag(session::cannot_mix_and_match_sanitizers)]
pub struct CannotMixAndMatchSanitizers {
pub first: String,
pub second: String,
}
#[derive(SessionDiagnostic)]
#[diag(session::cannot_enable_crt_static_linux)]
pub struct CannotEnableCrtStaticLinux;
#[derive(SessionDiagnostic)]
#[diag(session::sanitizer_cfi_enabled)]
pub struct SanitizerCfiEnabled;
#[derive(SessionDiagnostic)]
#[diag(session::unstable_virtual_function_elimination)]
pub struct UnstableVirtualFunctionElimination;
#[derive(SessionDiagnostic)]
#[diag(session::unsupported_dwarf_version)]
pub struct UnsupportedDwarfVersion {
pub dwarf_version: u32,
}
#[derive(SessionDiagnostic)]
#[diag(session::target_stack_protector_not_supported)]
pub struct StackProtectorNotSupportedForTarget<'a> {
pub stack_protector: StackProtector,
pub target_triple: &'a TargetTriple,
}
#[derive(SessionDiagnostic)]
#[diag(session::split_debuginfo_unstable_platform)]
pub struct SplitDebugInfoUnstablePlatform {
pub debuginfo: SplitDebuginfo,
}

View File

@ -2,6 +2,13 @@ use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
use crate::errors::{
CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
};
use crate::parse::{add_feature_diagnostics, ParseSess};
use crate::search_paths::{PathKind, SearchPath};
use crate::{filesearch, lint};
@ -235,6 +242,9 @@ impl Session {
if !unleashed_features.is_empty() {
let mut must_err = false;
// Create a diagnostic pointing at where things got unleashed.
// FIXME(#100717): needs eager translation/lists
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
let mut diag = self.struct_warn("skipping const checks");
for &(span, feature_gate) in unleashed_features.iter() {
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
@ -250,10 +260,7 @@ impl Session {
// If we should err, make sure we did.
if must_err && self.has_errors().is_none() {
// We have skipped a feature gate, and not run into other errors... reject.
self.err(
"`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
gates, except when testing error paths in the CTFE engine",
);
self.emit_err(NotCircumventFeature);
}
}
}
@ -534,9 +541,13 @@ impl Session {
Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
}
}
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().span_warn(sp, msg)
}
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@ -585,6 +596,8 @@ impl Session {
) {
self.diagnostic().span_note_without_error(sp, msg)
}
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_note_without_error(
&self,
msg: impl Into<DiagnosticMessage>,
@ -1469,40 +1482,28 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
&& sess.opts.cg.prefer_dynamic
&& sess.target.is_like_windows
{
sess.err(
"Linker plugin based LTO is not supported together with \
`-C prefer-dynamic` when targeting Windows-like targets",
);
sess.emit_err(LinkerPluginToWindowsNotSupported);
}
// Make sure that any given profiling data actually exists so LLVM can't
// decide to silently skip PGO.
if let Some(ref path) = sess.opts.cg.profile_use {
if !path.exists() {
sess.err(&format!(
"File `{}` passed to `-C profile-use` does not exist.",
path.display()
));
sess.emit_err(ProfileUseFileDoesNotExist { path });
}
}
// Do the same for sample profile data.
if let Some(ref path) = sess.opts.unstable_opts.profile_sample_use {
if !path.exists() {
sess.err(&format!(
"File `{}` passed to `-C profile-sample-use` does not exist.",
path.display()
));
sess.emit_err(ProfileSampleUseFileDoesNotExist { path });
}
}
// Unwind tables cannot be disabled if the target requires them.
if let Some(include_uwtables) = sess.opts.cg.force_unwind_tables {
if sess.target.requires_uwtable && !include_uwtables {
sess.err(
"target requires unwind tables, they cannot be disabled with \
`-C force-unwind-tables=no`.",
);
sess.emit_err(TargetRequiresUnwindTables);
}
}
@ -1512,64 +1513,55 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
match unsupported_sanitizers.into_iter().count() {
0 => {}
1 => {
sess.err(&format!(
"{} sanitizer is not supported for this target",
unsupported_sanitizers
));
sess.emit_err(SanitizerNotSupported { us: unsupported_sanitizers.to_string() });
}
_ => {
sess.err(&format!(
"{} sanitizers are not supported for this target",
unsupported_sanitizers
));
sess.emit_err(SanitizersNotSupported { us: unsupported_sanitizers.to_string() });
}
}
// Cannot mix and match sanitizers.
let mut sanitizer_iter = sess.opts.unstable_opts.sanitizer.into_iter();
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
sess.err(&format!("`-Zsanitizer={first}` is incompatible with `-Zsanitizer={second}`"));
sess.emit_err(CannotMixAndMatchSanitizers {
first: first.to_string(),
second: second.to_string(),
});
}
// Cannot enable crt-static with sanitizers on Linux
if sess.crt_static(None) && !sess.opts.unstable_opts.sanitizer.is_empty() {
sess.err(
"sanitizer is incompatible with statically linked libc, \
disable it using `-C target-feature=-crt-static`",
);
sess.emit_err(CannotEnableCrtStaticLinux);
}
// LLVM CFI and VFE both require LTO.
if sess.lto() != config::Lto::Fat {
if sess.is_sanitizer_cfi_enabled() {
sess.err("`-Zsanitizer=cfi` requires `-Clto`");
sess.emit_err(SanitizerCfiEnabled);
}
if sess.opts.unstable_opts.virtual_function_elimination {
sess.err("`-Zvirtual-function-elimination` requires `-Clto`");
sess.emit_err(UnstableVirtualFunctionElimination);
}
}
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
if !sess.target.options.supports_stack_protector {
sess.warn(&format!(
"`-Z stack-protector={}` is not supported for target {} and will be ignored",
sess.opts.unstable_opts.stack_protector, sess.opts.target_triple
))
sess.emit_warning(StackProtectorNotSupportedForTarget {
stack_protector: sess.opts.unstable_opts.stack_protector,
target_triple: &sess.opts.target_triple,
});
}
}
if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
if dwarf_version > 5 {
sess.err(&format!("requested DWARF version {} is greater than 5", dwarf_version));
sess.emit_err(UnsupportedDwarfVersion { dwarf_version });
}
}
if !sess.target.options.supported_split_debuginfo.contains(&sess.split_debuginfo())
&& !sess.opts.unstable_opts.unstable_options
{
sess.err(&format!(
"`-Csplit-debuginfo={}` is unstable on this platform",
sess.split_debuginfo()
));
sess.emit_err(SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() });
}
}
@ -1614,14 +1606,20 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
rustc_errors::Handler::with_emitter(true, None, emitter)
}
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed {
early_error_handler(output).struct_err(msg).emit()
}
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
early_error_handler(output).struct_fatal(msg).emit()
}
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
early_error_handler(output).struct_warn(msg).emit()
}

View File

@ -7,7 +7,7 @@ use crate::spec::Target;
use std::convert::{TryFrom, TryInto};
use std::fmt;
use std::iter::Step;
use std::num::NonZeroUsize;
use std::num::{NonZeroUsize, ParseIntError};
use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
use std::str::FromStr;
@ -69,34 +69,46 @@ impl Default for TargetDataLayout {
}
}
pub enum TargetDataLayoutErrors<'a> {
InvalidAddressSpace { addr_space: &'a str, cause: &'a str, err: ParseIntError },
InvalidBits { kind: &'a str, bit: &'a str, cause: &'a str, err: ParseIntError },
MissingAlignment { cause: &'a str },
InvalidAlignment { cause: &'a str, err: String },
InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
InconsistentTargetPointerWidth { pointer_size: u64, target: u32 },
InvalidBitsSize { err: String },
}
impl TargetDataLayout {
pub fn parse(target: &Target) -> Result<TargetDataLayout, String> {
pub fn parse<'a>(target: &'a Target) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
// Parse an address space index from a string.
let parse_address_space = |s: &str, cause: &str| {
let parse_address_space = |s: &'a str, cause: &'a str| {
s.parse::<u32>().map(AddressSpace).map_err(|err| {
format!("invalid address space `{}` for `{}` in \"data-layout\": {}", s, cause, err)
TargetDataLayoutErrors::InvalidAddressSpace { addr_space: s, cause, err }
})
};
// Parse a bit count from a string.
let parse_bits = |s: &str, kind: &str, cause: &str| {
s.parse::<u64>().map_err(|err| {
format!("invalid {} `{}` for `{}` in \"data-layout\": {}", kind, s, cause, err)
let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
s.parse::<u64>().map_err(|err| TargetDataLayoutErrors::InvalidBits {
kind,
bit: s,
cause,
err,
})
};
// Parse a size string.
let size = |s: &str, cause: &str| parse_bits(s, "size", cause).map(Size::from_bits);
let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
// Parse an alignment string.
let align = |s: &[&str], cause: &str| {
let align = |s: &[&'a str], cause: &'a str| {
if s.is_empty() {
return Err(format!("missing alignment for `{}` in \"data-layout\"", cause));
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
}
let align_from_bits = |bits| {
Align::from_bits(bits).map_err(|err| {
format!("invalid alignment for `{}` in \"data-layout\": {}", cause, err)
})
Align::from_bits(bits)
.map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
};
let abi = parse_bits(s[0], "alignment", cause)?;
let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?;
@ -158,25 +170,24 @@ impl TargetDataLayout {
// Perform consistency checks against the Target information.
if dl.endian != target.endian {
return Err(format!(
"inconsistent target specification: \"data-layout\" claims \
architecture is {}-endian, while \"target-endian\" is `{}`",
dl.endian.as_str(),
target.endian.as_str(),
));
return Err(TargetDataLayoutErrors::InconsistentTargetArchitecture {
dl: dl.endian.as_str(),
target: target.endian.as_str(),
});
}
let target_pointer_width: u64 = target.pointer_width.into();
if dl.pointer_size.bits() != target_pointer_width {
return Err(format!(
"inconsistent target specification: \"data-layout\" claims \
pointers are {}-bit, while \"target-pointer-width\" is `{}`",
dl.pointer_size.bits(),
target.pointer_width
));
return Err(TargetDataLayoutErrors::InconsistentTargetPointerWidth {
pointer_size: dl.pointer_size.bits(),
target: target.pointer_width,
});
}
dl.c_enum_min_size = Integer::from_size(Size::from_bits(target.c_enum_min_bits))?;
dl.c_enum_min_size = match Integer::from_size(Size::from_bits(target.c_enum_min_bits)) {
Ok(bits) => bits,
Err(err) => return Err(TargetDataLayoutErrors::InvalidBitsSize { err }),
};
Ok(dl)
}

View File

@ -25,8 +25,7 @@ use rustc_middle::hir::map;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, IsSuggestable,
ProjectionPredicate, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitable,
ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
};
use rustc_middle::ty::{TypeAndMut, TypeckResults};
use rustc_session::Limit;
@ -174,7 +173,7 @@ pub trait InferCtxtExt<'tcx> {
&self,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
proj_pred: Option<ty::PolyProjectionPredicate<'tcx>>,
associated_item: Option<(&'static str, Ty<'tcx>)>,
body_id: hir::HirId,
);
@ -467,7 +466,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
&self,
mut err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
proj_pred: Option<ty::PolyProjectionPredicate<'tcx>>,
associated_ty: Option<(&'static str, Ty<'tcx>)>,
body_id: hir::HirId,
) {
let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
@ -604,21 +603,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_pred.print_modifiers_and_trait_path().to_string()
);
if let Some(proj_pred) = proj_pred {
let ProjectionPredicate { projection_ty, term } = proj_pred.skip_binder();
let item = self.tcx.associated_item(projection_ty.item_def_id);
if let Some((name, term)) = associated_ty {
// FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
// That should be extracted into a helper function.
if constraint.ends_with('>') {
constraint = format!(
"{}, {}={}>",
"{}, {} = {}>",
&constraint[..constraint.len() - 1],
item.name,
name,
term
);
} else {
constraint.push_str(&format!("<{}={}>", item.name, term));
constraint.push_str(&format!("<{} = {}>", name, term));
}
}
@ -648,7 +644,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
..
}) if !param_ty => {
// Missing generic type parameter bound.
if suggest_arbitrary_trait_bound(self.tcx, generics, &mut err, trait_pred) {
if suggest_arbitrary_trait_bound(
self.tcx,
generics,
&mut err,
trait_pred,
associated_ty,
) {
return;
}
}

View File

@ -2940,8 +2940,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// though we can easily give a hint that ought to be
// relevant.
err.note(
"lifetimes appearing in an associated type are not considered constrained",
"lifetimes appearing in an associated or opaque type are not considered constrained",
);
err.note("consider introducing a named lifetime parameter");
}
err.emit();

View File

@ -409,7 +409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, ExprKind::Lit(_))),
output_pred: None,
output_ty: None,
},
),
self.param_env,

View File

@ -20,10 +20,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::{self, InferOk};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{
self, AssocKind, DefIdTree, GenericParamDefKind, ProjectionPredicate, ProjectionTy,
ToPredicate, Ty, TypeVisitable,
};
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TypeVisitable};
use rustc_span::symbol::Ident;
use rustc_span::Span;
use rustc_trait_selection::traits;
@ -337,22 +334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Construct an obligation
let poly_trait_ref = ty::Binder::dummy(trait_ref);
let opt_output_ty =
expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
let opt_output_assoc_item = self.tcx.associated_items(trait_def_id).find_by_name_and_kind(
self.tcx,
Ident::from_str("Output"),
AssocKind::Type,
trait_def_id,
);
let output_pred =
opt_output_ty.zip(opt_output_assoc_item).map(|(output_ty, output_assoc_item)| {
ty::Binder::dummy(ty::PredicateKind::Projection(ProjectionPredicate {
projection_ty: ProjectionTy { substs, item_def_id: output_assoc_item.def_id },
term: output_ty.into(),
}))
.to_predicate(self.tcx)
});
let output_ty = expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
(
traits::Obligation::new(
@ -363,7 +345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
output_pred,
output_ty,
},
),
self.param_env,
@ -518,7 +500,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
output_pred: None,
output_ty: None,
},
)
} else {

View File

@ -11,9 +11,8 @@ use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
@ -22,8 +21,6 @@ use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt as
use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt};
use rustc_type_ir::sty::TyKind::*;
use std::ops::ControlFlow;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Checks a `a <op>= b`
pub fn check_binop_assign(
@ -313,8 +310,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// error types are considered "builtin"
Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(),
Err(errors) => {
let source_map = self.tcx.sess.source_map();
let (mut err, missing_trait, use_output) = match is_assign {
let (_, trait_def_id) =
lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
let missing_trait = trait_def_id
.map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id)));
let (mut err, output_def_id) = match is_assign {
IsAssign::Yes => {
let mut err = struct_span_err!(
self.tcx.sess,
@ -328,112 +328,63 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs_expr.span,
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
);
let missing_trait = match op.node {
hir::BinOpKind::Add => Some("std::ops::AddAssign"),
hir::BinOpKind::Sub => Some("std::ops::SubAssign"),
hir::BinOpKind::Mul => Some("std::ops::MulAssign"),
hir::BinOpKind::Div => Some("std::ops::DivAssign"),
hir::BinOpKind::Rem => Some("std::ops::RemAssign"),
hir::BinOpKind::BitAnd => Some("std::ops::BitAndAssign"),
hir::BinOpKind::BitXor => Some("std::ops::BitXorAssign"),
hir::BinOpKind::BitOr => Some("std::ops::BitOrAssign"),
hir::BinOpKind::Shl => Some("std::ops::ShlAssign"),
hir::BinOpKind::Shr => Some("std::ops::ShrAssign"),
_ => None,
};
self.note_unmet_impls_on_type(&mut err, errors);
(err, missing_trait, false)
(err, None)
}
IsAssign::No => {
let (message, missing_trait, use_output) = match op.node {
hir::BinOpKind::Add => (
format!("cannot add `{rhs_ty}` to `{lhs_ty}`"),
Some("std::ops::Add"),
true,
),
hir::BinOpKind::Sub => (
format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`"),
Some("std::ops::Sub"),
true,
),
hir::BinOpKind::Mul => (
format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`"),
Some("std::ops::Mul"),
true,
),
hir::BinOpKind::Div => (
format!("cannot divide `{lhs_ty}` by `{rhs_ty}`"),
Some("std::ops::Div"),
true,
),
hir::BinOpKind::Rem => (
format!("cannot mod `{lhs_ty}` by `{rhs_ty}`"),
Some("std::ops::Rem"),
true,
),
hir::BinOpKind::BitAnd => (
format!("no implementation for `{lhs_ty} & {rhs_ty}`"),
Some("std::ops::BitAnd"),
true,
),
hir::BinOpKind::BitXor => (
format!("no implementation for `{lhs_ty} ^ {rhs_ty}`"),
Some("std::ops::BitXor"),
true,
),
hir::BinOpKind::BitOr => (
format!("no implementation for `{lhs_ty} | {rhs_ty}`"),
Some("std::ops::BitOr"),
true,
),
hir::BinOpKind::Shl => (
format!("no implementation for `{lhs_ty} << {rhs_ty}`"),
Some("std::ops::Shl"),
true,
),
hir::BinOpKind::Shr => (
format!("no implementation for `{lhs_ty} >> {rhs_ty}`"),
Some("std::ops::Shr"),
true,
),
hir::BinOpKind::Eq | hir::BinOpKind::Ne => (
format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty
),
Some("std::cmp::PartialEq"),
false,
),
hir::BinOpKind::Lt
| hir::BinOpKind::Le
| hir::BinOpKind::Gt
| hir::BinOpKind::Ge => (
format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty
),
Some("std::cmp::PartialOrd"),
false,
),
_ => (
format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty
),
None,
false,
let message = match op.node {
hir::BinOpKind::Add => {
format!("cannot add `{rhs_ty}` to `{lhs_ty}`")
}
hir::BinOpKind::Sub => {
format!("cannot subtract `{rhs_ty}` from `{lhs_ty}`")
}
hir::BinOpKind::Mul => {
format!("cannot multiply `{lhs_ty}` by `{rhs_ty}`")
}
hir::BinOpKind::Div => {
format!("cannot divide `{lhs_ty}` by `{rhs_ty}`")
}
hir::BinOpKind::Rem => {
format!("cannot mod `{lhs_ty}` by `{rhs_ty}`")
}
hir::BinOpKind::BitAnd => {
format!("no implementation for `{lhs_ty} & {rhs_ty}`")
}
hir::BinOpKind::BitXor => {
format!("no implementation for `{lhs_ty} ^ {rhs_ty}`")
}
hir::BinOpKind::BitOr => {
format!("no implementation for `{lhs_ty} | {rhs_ty}`")
}
hir::BinOpKind::Shl => {
format!("no implementation for `{lhs_ty} << {rhs_ty}`")
}
hir::BinOpKind::Shr => {
format!("no implementation for `{lhs_ty} >> {rhs_ty}`")
}
_ => format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty
),
};
let output_def_id = trait_def_id.and_then(|def_id| {
self.tcx
.associated_item_def_ids(def_id)
.iter()
.find(|item_def_id| {
self.tcx.associated_item(*item_def_id).name == sym::Output
})
.cloned()
});
let mut err = struct_span_err!(self.tcx.sess, op.span, E0369, "{message}");
if !lhs_expr.span.eq(&rhs_expr.span) {
err.span_label(lhs_expr.span, lhs_ty.to_string());
err.span_label(rhs_expr.span, rhs_ty.to_string());
}
self.note_unmet_impls_on_type(&mut err, errors);
(err, missing_trait, use_output)
(err, output_def_id)
}
};
@ -448,24 +399,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)
.is_ok()
{
if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
let msg = &format!(
"`{}{}` can be used on `{}`, you can dereference `{}`",
op.node.as_str(),
match is_assign {
IsAssign::Yes => "=",
IsAssign::No => "",
},
lhs_deref_ty.peel_refs(),
lstring,
);
err.span_suggestion_verbose(
lhs_expr.span.shrink_to_lo(),
msg,
"*",
rustc_errors::Applicability::MachineApplicable,
);
}
let msg = &format!(
"`{}{}` can be used on `{}` if you dereference the left-hand side",
op.node.as_str(),
match is_assign {
IsAssign::Yes => "=",
IsAssign::No => "",
},
lhs_deref_ty,
);
err.span_suggestion_verbose(
lhs_expr.span.shrink_to_lo(),
msg,
"*",
rustc_errors::Applicability::MachineApplicable,
);
}
};
@ -514,9 +462,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if let Some(missing_trait) = missing_trait {
let mut visitor = TypeParamVisitor(vec![]);
visitor.visit_ty(lhs_ty);
if op.node == hir::BinOpKind::Add
&& self.check_str_addition(
lhs_expr, rhs_expr, lhs_ty, rhs_ty, &mut err, is_assign, op,
@ -525,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// This has nothing here because it means we did string
// concatenation (e.g., "Hello " + "World!"). This means
// we don't want the note in the else clause to be emitted
} else if let [ty] = &visitor.0[..] {
} else if lhs_ty.has_param_types_or_consts() {
// Look for a TraitPredicate in the Fulfillment errors,
// and use it to generate a suggestion.
//
@ -547,12 +492,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(trait_pred) =
error.obligation.predicate.to_opt_poly_trait_pred()
{
let proj_pred = match error.obligation.cause.code() {
let output_associated_item = match error.obligation.cause.code()
{
ObligationCauseCode::BinOp {
output_pred: Some(output_pred),
output_ty: Some(output_ty),
..
} if use_output => {
output_pred.to_opt_poly_projection_pred()
} => {
// Make sure that we're attaching `Output = ..` to the right trait predicate
if let Some(output_def_id) = output_def_id
&& let Some(trait_def_id) = trait_def_id
&& self.tcx.parent(output_def_id) == trait_def_id
{
Some(("Output", *output_ty))
} else {
None
}
}
_ => None,
};
@ -560,12 +514,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_restricting_param_bound(
&mut err,
trait_pred,
proj_pred,
output_associated_item,
self.body_id,
);
}
}
} else if *ty != lhs_ty {
} else {
// When we know that a missing bound is responsible, we don't show
// this note as it is redundant.
err.note(&format!(
@ -702,14 +656,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("cannot apply unary operator `{}`", op.as_str()),
);
let mut visitor = TypeParamVisitor(vec![]);
visitor.visit_ty(operand_ty);
if let [_] = &visitor.0[..] && let ty::Param(_) = *operand_ty.kind() {
let predicates = errors
.iter()
.filter_map(|error| {
error.obligation.predicate.to_opt_poly_trait_pred()
});
if operand_ty.has_param_types_or_consts() {
let predicates = errors.iter().filter_map(|error| {
error.obligation.predicate.to_opt_poly_trait_pred()
});
for pred in predicates {
self.suggest_restricting_param_bound(
&mut err,
@ -777,64 +727,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
op: Op,
expected: Expectation<'tcx>,
) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
let lang = self.tcx.lang_items();
let span = match op {
Op::Binary(op, _) => op.span,
Op::Unary(_, span) => span,
};
let (opname, trait_did) = if let Op::Binary(op, IsAssign::Yes) = op {
match op.node {
hir::BinOpKind::Add => (sym::add_assign, lang.add_assign_trait()),
hir::BinOpKind::Sub => (sym::sub_assign, lang.sub_assign_trait()),
hir::BinOpKind::Mul => (sym::mul_assign, lang.mul_assign_trait()),
hir::BinOpKind::Div => (sym::div_assign, lang.div_assign_trait()),
hir::BinOpKind::Rem => (sym::rem_assign, lang.rem_assign_trait()),
hir::BinOpKind::BitXor => (sym::bitxor_assign, lang.bitxor_assign_trait()),
hir::BinOpKind::BitAnd => (sym::bitand_assign, lang.bitand_assign_trait()),
hir::BinOpKind::BitOr => (sym::bitor_assign, lang.bitor_assign_trait()),
hir::BinOpKind::Shl => (sym::shl_assign, lang.shl_assign_trait()),
hir::BinOpKind::Shr => (sym::shr_assign, lang.shr_assign_trait()),
hir::BinOpKind::Lt
| hir::BinOpKind::Le
| hir::BinOpKind::Ge
| hir::BinOpKind::Gt
| hir::BinOpKind::Eq
| hir::BinOpKind::Ne
| hir::BinOpKind::And
| hir::BinOpKind::Or => {
span_bug!(span, "impossible assignment operation: {}=", op.node.as_str())
}
}
} else if let Op::Binary(op, IsAssign::No) = op {
match op.node {
hir::BinOpKind::Add => (sym::add, lang.add_trait()),
hir::BinOpKind::Sub => (sym::sub, lang.sub_trait()),
hir::BinOpKind::Mul => (sym::mul, lang.mul_trait()),
hir::BinOpKind::Div => (sym::div, lang.div_trait()),
hir::BinOpKind::Rem => (sym::rem, lang.rem_trait()),
hir::BinOpKind::BitXor => (sym::bitxor, lang.bitxor_trait()),
hir::BinOpKind::BitAnd => (sym::bitand, lang.bitand_trait()),
hir::BinOpKind::BitOr => (sym::bitor, lang.bitor_trait()),
hir::BinOpKind::Shl => (sym::shl, lang.shl_trait()),
hir::BinOpKind::Shr => (sym::shr, lang.shr_trait()),
hir::BinOpKind::Lt => (sym::lt, lang.partial_ord_trait()),
hir::BinOpKind::Le => (sym::le, lang.partial_ord_trait()),
hir::BinOpKind::Ge => (sym::ge, lang.partial_ord_trait()),
hir::BinOpKind::Gt => (sym::gt, lang.partial_ord_trait()),
hir::BinOpKind::Eq => (sym::eq, lang.eq_trait()),
hir::BinOpKind::Ne => (sym::ne, lang.eq_trait()),
hir::BinOpKind::And | hir::BinOpKind::Or => {
span_bug!(span, "&& and || are not overloadable")
}
}
} else if let Op::Unary(hir::UnOp::Not, _) = op {
(sym::not, lang.not_trait())
} else if let Op::Unary(hir::UnOp::Neg, _) = op {
(sym::neg, lang.neg_trait())
} else {
bug!("lookup_op_method: op not supported: {:?}", op)
};
let (opname, trait_did) = lang_item_for_op(self.tcx, op, span);
debug!(
"lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})",
@ -895,6 +792,66 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
fn lang_item_for_op(
tcx: TyCtxt<'_>,
op: Op,
span: Span,
) -> (rustc_span::Symbol, Option<hir::def_id::DefId>) {
let lang = tcx.lang_items();
if let Op::Binary(op, IsAssign::Yes) = op {
match op.node {
hir::BinOpKind::Add => (sym::add_assign, lang.add_assign_trait()),
hir::BinOpKind::Sub => (sym::sub_assign, lang.sub_assign_trait()),
hir::BinOpKind::Mul => (sym::mul_assign, lang.mul_assign_trait()),
hir::BinOpKind::Div => (sym::div_assign, lang.div_assign_trait()),
hir::BinOpKind::Rem => (sym::rem_assign, lang.rem_assign_trait()),
hir::BinOpKind::BitXor => (sym::bitxor_assign, lang.bitxor_assign_trait()),
hir::BinOpKind::BitAnd => (sym::bitand_assign, lang.bitand_assign_trait()),
hir::BinOpKind::BitOr => (sym::bitor_assign, lang.bitor_assign_trait()),
hir::BinOpKind::Shl => (sym::shl_assign, lang.shl_assign_trait()),
hir::BinOpKind::Shr => (sym::shr_assign, lang.shr_assign_trait()),
hir::BinOpKind::Lt
| hir::BinOpKind::Le
| hir::BinOpKind::Ge
| hir::BinOpKind::Gt
| hir::BinOpKind::Eq
| hir::BinOpKind::Ne
| hir::BinOpKind::And
| hir::BinOpKind::Or => {
span_bug!(span, "impossible assignment operation: {}=", op.node.as_str())
}
}
} else if let Op::Binary(op, IsAssign::No) = op {
match op.node {
hir::BinOpKind::Add => (sym::add, lang.add_trait()),
hir::BinOpKind::Sub => (sym::sub, lang.sub_trait()),
hir::BinOpKind::Mul => (sym::mul, lang.mul_trait()),
hir::BinOpKind::Div => (sym::div, lang.div_trait()),
hir::BinOpKind::Rem => (sym::rem, lang.rem_trait()),
hir::BinOpKind::BitXor => (sym::bitxor, lang.bitxor_trait()),
hir::BinOpKind::BitAnd => (sym::bitand, lang.bitand_trait()),
hir::BinOpKind::BitOr => (sym::bitor, lang.bitor_trait()),
hir::BinOpKind::Shl => (sym::shl, lang.shl_trait()),
hir::BinOpKind::Shr => (sym::shr, lang.shr_trait()),
hir::BinOpKind::Lt => (sym::lt, lang.partial_ord_trait()),
hir::BinOpKind::Le => (sym::le, lang.partial_ord_trait()),
hir::BinOpKind::Ge => (sym::ge, lang.partial_ord_trait()),
hir::BinOpKind::Gt => (sym::gt, lang.partial_ord_trait()),
hir::BinOpKind::Eq => (sym::eq, lang.eq_trait()),
hir::BinOpKind::Ne => (sym::ne, lang.eq_trait()),
hir::BinOpKind::And | hir::BinOpKind::Or => {
span_bug!(span, "&& and || are not overloadable")
}
}
} else if let Op::Unary(hir::UnOp::Not, _) = op {
(sym::not, lang.not_trait())
} else if let Op::Unary(hir::UnOp::Neg, _) = op {
(sym::neg, lang.neg_trait())
} else {
bug!("lookup_op_method: op not supported: {:?}", op)
}
}
// Binary operator categories. These categories summarize the behavior
// with respect to the builtin operations supported.
enum BinOpCategory {
@ -1017,17 +974,6 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool
}
}
struct TypeParamVisitor<'tcx>(Vec<Ty<'tcx>>);
impl<'tcx> TypeVisitor<'tcx> for TypeParamVisitor<'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::Param(_) = ty.kind() {
self.0.push(ty);
}
ty.super_visit_with(self)
}
}
struct TypeParamEraser<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, Span);
impl<'tcx> TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> {

View File

@ -21,7 +21,7 @@ use rustc_span::source_map;
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
reg.lint_store.register_late_pass(|| Box::new(MissingAllowedAttrPass));
reg.lint_store.register_late_pass(|_| Box::new(MissingAllowedAttrPass));
}
declare_lint! {

View File

@ -74,7 +74,7 @@ fn __rustc_plugin_registrar(reg: &mut Registry) {
&CRATE_NOT_GREY,
&CRATE_NOT_GREEN,
]);
reg.lint_store.register_late_pass(|| Box::new(PassOkay));
reg.lint_store.register_late_pass(|| Box::new(PassRedBlue));
reg.lint_store.register_late_pass(|| Box::new(PassGreyGreen));
reg.lint_store.register_late_pass(|_| Box::new(PassOkay));
reg.lint_store.register_late_pass(|_| Box::new(PassRedBlue));
reg.lint_store.register_late_pass(|_| Box::new(PassGreyGreen));
}

View File

@ -39,5 +39,5 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
reg.lint_store.register_late_pass(|| Box::new(Pass));
reg.lint_store.register_late_pass(|_| Box::new(Pass));
}

View File

@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]);
reg.lint_store.register_late_pass(|| Box::new(Pass));
reg.lint_store.register_late_pass(|_| Box::new(Pass));
reg.lint_store.register_group(
true,
"lint_me",

View File

@ -10,6 +10,7 @@ impl T<'_> for S {
fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
//~^ ERROR binding for associated type `Output` references an anonymous lifetime
//~^^ NOTE lifetimes appearing in an associated type are not considered constrained
//~| NOTE lifetimes appearing in an associated or opaque type are not considered constrained
//~| NOTE consider introducing a named lifetime parameter
fn main() {}

View File

@ -4,7 +4,8 @@ error[E0582]: binding for associated type `Output` references an anonymous lifet
LL | fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
| ^^^^^^^^^^^^^^^
|
= note: lifetimes appearing in an associated type are not considered constrained
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error: aborting due to previous error

View File

@ -6,7 +6,7 @@ LL | x % 2 == 0
| |
| &&{integer}
|
help: `%` can be used on `{integer}`, you can dereference `x`
help: `%` can be used on `&{integer}` if you dereference the left-hand side
|
LL | *x % 2 == 0
| +

View File

@ -24,7 +24,7 @@ impl<B: Add + Add<Output = B>> Add for C<B> {
struct D<B>(B);
impl<B: std::ops::Add<Output=B>> Add for D<B> {
impl<B: std::ops::Add<Output = B>> Add for D<B> {
type Output = Self;
fn add(self, rhs: Self) -> Self {

View File

@ -66,8 +66,8 @@ LL | Self(self.0 + rhs.0)
|
help: consider restricting type parameter `B`
|
LL | impl<B: std::ops::Add<Output=B>> Add for D<B> {
| +++++++++++++++++++++++++
LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
| +++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/missing-bounds.rs:42:14

View File

@ -4,7 +4,8 @@ error[E0581]: return type references an anonymous lifetime, which is not constra
LL | fn f(_: X) -> X {
| ^
|
= note: lifetimes appearing in an associated type are not considered constrained
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
--> $DIR/issue-47511.rs:12:23

View File

@ -0,0 +1,10 @@
// run-rustfix
#[allow(dead_code)]
enum Demo {
A = 1,
B = 2 //~ ERROR unexpected `==`
//~^ expected item, found `==`
}
fn main() {}

View File

@ -0,0 +1,10 @@
// run-rustfix
#[allow(dead_code)]
enum Demo {
A = 1,
B == 2 //~ ERROR unexpected `==`
//~^ expected item, found `==`
}
fn main() {}

View File

@ -0,0 +1,14 @@
error: unexpected `==`
--> $DIR/issue-101477-enum.rs:6:7
|
LL | B == 2
| ^^ help: try using `=` instead
error: expected item, found `==`
--> $DIR/issue-101477-enum.rs:6:7
|
LL | B == 2
| ^^ expected item
error: aborting due to 2 previous errors

View File

@ -0,0 +1,6 @@
// run-rustfix
fn main() {
let x = 2; //~ ERROR unexpected `==`
println!("x: {}", x)
}

View File

@ -0,0 +1,6 @@
// run-rustfix
fn main() {
let x == 2; //~ ERROR unexpected `==`
println!("x: {}", x)
}

View File

@ -0,0 +1,8 @@
error: unexpected `==`
--> $DIR/issue-101477-let.rs:4:11
|
LL | let x == 2;
| ^^ help: try using `=` instead
error: aborting due to previous error

View File

@ -1,6 +1,6 @@
// run-rustfix
fn add_ten<N: std::ops::Add<i32, Output=N>>(n: N) -> N {
fn add_ten<N: std::ops::Add<i32, Output = N>>(n: N) -> N {
n + 10
//~^ ERROR cannot add `{integer}` to `N`
}

View File

@ -8,8 +8,8 @@ LL | n + 10
|
help: consider restricting type parameter `N`
|
LL | fn add_ten<N: std::ops::Add<i32, Output=N>>(n: N) -> N {
| ++++++++++++++++++++++++++++++
LL | fn add_ten<N: std::ops::Add<i32, Output = N>>(n: N) -> N {
| ++++++++++++++++++++++++++++++++
error: aborting due to previous error

View File

@ -0,0 +1,12 @@
use std::ops::Add;
struct Wrapper<T>(T);
trait Foo {}
fn qux<T>(a: Wrapper<T>, b: T) -> T {
a + b
//~^ ERROR cannot add `T` to `Wrapper<T>`
}
fn main() {}

View File

@ -0,0 +1,26 @@
error[E0369]: cannot add `T` to `Wrapper<T>`
--> $DIR/restrict-type-not-param.rs:8:7
|
LL | a + b
| - ^ - T
| |
| Wrapper<T>
|
note: an implementation of `Add<_>` might be missing for `Wrapper<T>`
--> $DIR/restrict-type-not-param.rs:3:1
|
LL | struct Wrapper<T>(T);
| ^^^^^^^^^^^^^^^^^ must implement `Add<_>`
note: the following trait must be implemented
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
LL | pub trait Add<Rhs = Self> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn qux<T>(a: Wrapper<T>, b: T) -> T where Wrapper<T>: Add<T, Output = T> {
| ++++++++++++++++++++++++++++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.

View File

@ -8,8 +8,8 @@ LL | a * b
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64> {
| ++++++++++++++++++
LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64, Output = f64> {
| ++++++++++++++++++++++++++++++++
error: aborting due to previous error

View File

@ -1,17 +1,33 @@
// check-pass
#![feature(type_alias_impl_trait)]
mod foo {
mod lifetime_params {
type Ty<'a> = impl Sized;
fn defining(s: &str) -> Ty<'_> { s }
fn execute(ty: Ty<'_>) -> &str { todo!() }
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
type BadFnSig = fn(Ty<'_>) -> &str;
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
//~^ ERROR binding for associated type `Output` references an anonymous lifetime
}
mod bar {
mod lifetime_params_2 {
type Ty<'a> = impl FnOnce() -> &'a str;
fn defining(s: &str) -> Ty<'_> { move || s }
fn execute(ty: Ty<'_>) -> &str { ty() }
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
}
// regression test for https://github.com/rust-lang/rust/issues/97104
mod type_params {
type Ty<T> = impl Sized;
fn define<T>(s: T) -> Ty<T> { s }
type BadFnSig = fn(Ty<&str>) -> &str;
//~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
//~^ ERROR binding for associated type `Output` references an anonymous lifetime
}
fn main() {}

View File

@ -0,0 +1,58 @@
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:6:31
|
LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
| ^^^^
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:9:35
|
LL | type BadFnSig = fn(Ty<'_>) -> &str;
| ^^^^
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
--> $DIR/constrain_inputs.rs:11:42
|
LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
| ^^^^
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:18:31
|
LL | fn execute(ty: Ty<'_>) -> &str { ty() }
| ^^^^
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:27:37
|
LL | type BadFnSig = fn(Ty<&str>) -> &str;
| ^^^^
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
--> $DIR/constrain_inputs.rs:29:44
|
LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
| ^^^^
|
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0581, E0582.
For more information about an error, try `rustc --explain E0581`.

View File

@ -0,0 +1,31 @@
#![feature(type_alias_impl_trait)]
trait Static: 'static {}
impl Static for () {}
type Gal<T> = impl Static;
fn _defining<T>() -> Gal<T> {}
trait Callable<Arg> { type Output; }
/// We can infer `<C as Callable<Arg>>::Output: 'static`,
/// because we know `C: 'static` and `Arg: 'static`,
fn box_str<C, Arg>(s: C::Output) -> Box<dyn AsRef<str> + 'static>
where
Arg: Static,
C: ?Sized + Callable<Arg> + 'static,
C::Output: AsRef<str>,
{
Box::new(s)
}
fn extend_lifetime(s: &str) -> Box<dyn AsRef<str> + 'static> {
type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
//~^ ERROR binding for associated type `Output` references lifetime `'a`
box_str::<MalformedTy, _>(s)
}
fn main() {
let extended = extend_lifetime(&String::from("hello"));
println!("{}", extended.as_ref().as_ref());
}

View File

@ -0,0 +1,9 @@
error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
--> $DIR/constrain_inputs_unsound.rs:23:58
|
LL | type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
| ^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0582`.

View File

@ -19,7 +19,7 @@ LL | x.lock().unwrap() += 1;
| |
| cannot use `+=` on type `MutexGuard<'_, usize>`
|
help: `+=` can be used on `usize`, you can dereference `x.lock().unwrap()`
help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *x.lock().unwrap() += 1;
| +
@ -47,7 +47,7 @@ LL | y += 1;
| |
| cannot use `+=` on type `MutexGuard<'_, usize>`
|
help: `+=` can be used on `usize`, you can dereference `y`
help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *y += 1;
| +

View File

@ -19,7 +19,7 @@ LL | x.last_mut().unwrap() += 1;
| |
| cannot use `+=` on type `&mut usize`
|
help: `+=` can be used on `usize`, you can dereference `x.last_mut().unwrap()`
help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *x.last_mut().unwrap() += 1;
| +
@ -45,7 +45,7 @@ LL | y += 1;
| |
| cannot use `+=` on type `&mut usize`
|
help: `+=` can be used on `usize`, you can dereference `y`
help: `+=` can be used on `usize` if you dereference the left-hand side
|
LL | *y += 1;
| +

View File

@ -120,15 +120,17 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
let new_lint = if enable_msrv {
format!(
"store.register_{lint_pass}_pass(move || Box::new({module_name}::{camel_name}::new(msrv)));\n ",
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv)));\n ",
lint_pass = lint.pass,
ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
camel_name = to_camel_case(lint.name),
)
} else {
format!(
"store.register_{lint_pass}_pass(|| Box::new({module_name}::{camel_name}));\n ",
"store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ",
lint_pass = lint.pass,
ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
camel_name = to_camel_case(lint.name),
)

View File

@ -523,7 +523,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
#[cfg(feature = "internal")]
{
if std::env::var("ENABLE_METADATA_COLLECTION").eq(&Ok("1".to_string())) {
store.register_late_pass(|| Box::new(utils::internal_lints::metadata_collector::MetadataCollector::new()));
store.register_late_pass(|_| Box::new(utils::internal_lints::metadata_collector::MetadataCollector::new()));
return;
}
}
@ -533,69 +533,69 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
{
store.register_early_pass(|| Box::new(utils::internal_lints::ClippyLintsInternal));
store.register_early_pass(|| Box::new(utils::internal_lints::ProduceIce));
store.register_late_pass(|| Box::new(utils::internal_lints::CollapsibleCalls));
store.register_late_pass(|| Box::new(utils::internal_lints::CompilerLintFunctions::new()));
store.register_late_pass(|| Box::new(utils::internal_lints::IfChainStyle));
store.register_late_pass(|| Box::new(utils::internal_lints::InvalidPaths));
store.register_late_pass(|| Box::new(utils::internal_lints::InterningDefinedSymbol::default()));
store.register_late_pass(|| Box::new(utils::internal_lints::LintWithoutLintPass::default()));
store.register_late_pass(|| Box::new(utils::internal_lints::MatchTypeOnDiagItem));
store.register_late_pass(|| Box::new(utils::internal_lints::OuterExpnDataPass));
store.register_late_pass(|| Box::new(utils::internal_lints::MsrvAttrImpl));
store.register_late_pass(|_| Box::new(utils::internal_lints::CollapsibleCalls));
store.register_late_pass(|_| Box::new(utils::internal_lints::CompilerLintFunctions::new()));
store.register_late_pass(|_| Box::new(utils::internal_lints::IfChainStyle));
store.register_late_pass(|_| Box::new(utils::internal_lints::InvalidPaths));
store.register_late_pass(|_| Box::new(utils::internal_lints::InterningDefinedSymbol::default()));
store.register_late_pass(|_| Box::new(utils::internal_lints::LintWithoutLintPass::default()));
store.register_late_pass(|_| Box::new(utils::internal_lints::MatchTypeOnDiagItem));
store.register_late_pass(|_| Box::new(utils::internal_lints::OuterExpnDataPass));
store.register_late_pass(|_| Box::new(utils::internal_lints::MsrvAttrImpl));
}
let arithmetic_allowed = conf.arithmetic_allowed.clone();
store.register_late_pass(move || Box::new(operators::arithmetic::Arithmetic::new(arithmetic_allowed.clone())));
store.register_late_pass(|| Box::new(utils::dump_hir::DumpHir));
store.register_late_pass(|| Box::new(utils::author::Author));
store.register_late_pass(move |_| Box::new(operators::arithmetic::Arithmetic::new(arithmetic_allowed.clone())));
store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
store.register_late_pass(|_| Box::new(utils::author::Author));
let await_holding_invalid_types = conf.await_holding_invalid_types.clone();
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(await_holding_invalid::AwaitHolding::new(
await_holding_invalid_types.clone(),
))
});
store.register_late_pass(|| Box::new(serde_api::SerdeApi));
store.register_late_pass(|_| Box::new(serde_api::SerdeApi));
let vec_box_size_threshold = conf.vec_box_size_threshold;
let type_complexity_threshold = conf.type_complexity_threshold;
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(types::Types::new(
vec_box_size_threshold,
type_complexity_threshold,
avoid_breaking_exported_api,
))
});
store.register_late_pass(|| Box::new(booleans::NonminimalBool));
store.register_late_pass(|| Box::new(enum_clike::UnportableVariant));
store.register_late_pass(|| Box::new(float_literal::FloatLiteral));
store.register_late_pass(|| Box::new(ptr::Ptr));
store.register_late_pass(|| Box::new(needless_bool::NeedlessBool));
store.register_late_pass(|| Box::new(needless_bool::BoolComparison));
store.register_late_pass(|| Box::new(needless_for_each::NeedlessForEach));
store.register_late_pass(|| Box::new(misc::MiscLints));
store.register_late_pass(|| Box::new(eta_reduction::EtaReduction));
store.register_late_pass(|| Box::new(mut_mut::MutMut));
store.register_late_pass(|| Box::new(mut_reference::UnnecessaryMutPassed));
store.register_late_pass(|| Box::new(len_zero::LenZero));
store.register_late_pass(|| Box::new(attrs::Attributes));
store.register_late_pass(|| Box::new(blocks_in_if_conditions::BlocksInIfConditions));
store.register_late_pass(|| Box::new(unicode::Unicode));
store.register_late_pass(|| Box::new(uninit_vec::UninitVec));
store.register_late_pass(|| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
store.register_late_pass(|| Box::new(strings::StringAdd));
store.register_late_pass(|| Box::new(implicit_return::ImplicitReturn));
store.register_late_pass(|| Box::new(implicit_saturating_sub::ImplicitSaturatingSub));
store.register_late_pass(|| Box::new(default_numeric_fallback::DefaultNumericFallback));
store.register_late_pass(|| Box::new(inconsistent_struct_constructor::InconsistentStructConstructor));
store.register_late_pass(|| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
store.register_late_pass(|_| Box::new(booleans::NonminimalBool));
store.register_late_pass(|_| Box::new(enum_clike::UnportableVariant));
store.register_late_pass(|_| Box::new(float_literal::FloatLiteral));
store.register_late_pass(|_| Box::new(ptr::Ptr));
store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
store.register_late_pass(|_| Box::new(misc::MiscLints));
store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
store.register_late_pass(|_| Box::new(mut_mut::MutMut));
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
store.register_late_pass(|_| Box::new(len_zero::LenZero));
store.register_late_pass(|_| Box::new(attrs::Attributes));
store.register_late_pass(|_| Box::new(blocks_in_if_conditions::BlocksInIfConditions));
store.register_late_pass(|_| Box::new(unicode::Unicode));
store.register_late_pass(|_| Box::new(uninit_vec::UninitVec));
store.register_late_pass(|_| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
store.register_late_pass(|_| Box::new(strings::StringAdd));
store.register_late_pass(|_| Box::new(implicit_return::ImplicitReturn));
store.register_late_pass(|_| Box::new(implicit_saturating_sub::ImplicitSaturatingSub));
store.register_late_pass(|_| Box::new(default_numeric_fallback::DefaultNumericFallback));
store.register_late_pass(|_| Box::new(inconsistent_struct_constructor::InconsistentStructConstructor));
store.register_late_pass(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
let msrv = read_msrv(conf, sess);
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
let allow_expect_in_tests = conf.allow_expect_in_tests;
let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
store.register_late_pass(move || {
store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv)));
store.register_late_pass(move |_| {
Box::new(methods::Methods::new(
avoid_breaking_exported_api,
msrv,
@ -603,74 +603,74 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
allow_unwrap_in_tests,
))
});
store.register_late_pass(move || Box::new(matches::Matches::new(msrv)));
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv)));
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
store.register_late_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
store.register_late_pass(move || Box::new(manual_strip::ManualStrip::new(msrv)));
store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv)));
store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv)));
store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(msrv)));
store.register_late_pass(move || Box::new(checked_conversions::CheckedConversions::new(msrv)));
store.register_late_pass(move || Box::new(mem_replace::MemReplace::new(msrv)));
store.register_late_pass(move || Box::new(ranges::Ranges::new(msrv)));
store.register_late_pass(move || Box::new(from_over_into::FromOverInto::new(msrv)));
store.register_late_pass(move || Box::new(use_self::UseSelf::new(msrv)));
store.register_late_pass(move || Box::new(missing_const_for_fn::MissingConstForFn::new(msrv)));
store.register_late_pass(move || Box::new(needless_question_mark::NeedlessQuestionMark));
store.register_late_pass(move || Box::new(casts::Casts::new(msrv)));
store.register_late_pass(move |_| Box::new(checked_conversions::CheckedConversions::new(msrv)));
store.register_late_pass(move |_| Box::new(mem_replace::MemReplace::new(msrv)));
store.register_late_pass(move |_| Box::new(ranges::Ranges::new(msrv)));
store.register_late_pass(move |_| Box::new(from_over_into::FromOverInto::new(msrv)));
store.register_late_pass(move |_| Box::new(use_self::UseSelf::new(msrv)));
store.register_late_pass(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(msrv)));
store.register_late_pass(move |_| Box::new(needless_question_mark::NeedlessQuestionMark));
store.register_late_pass(move |_| Box::new(casts::Casts::new(msrv)));
store.register_early_pass(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(msrv)));
store.register_late_pass(|| Box::new(size_of_in_element_count::SizeOfInElementCount));
store.register_late_pass(|| Box::new(same_name_method::SameNameMethod));
store.register_late_pass(|_| Box::new(size_of_in_element_count::SizeOfInElementCount));
store.register_late_pass(|_| Box::new(same_name_method::SameNameMethod));
let max_suggested_slice_pattern_length = conf.max_suggested_slice_pattern_length;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(index_refutable_slice::IndexRefutableSlice::new(
max_suggested_slice_pattern_length,
msrv,
))
});
store.register_late_pass(|| Box::new(shadow::Shadow::default()));
store.register_late_pass(|| Box::new(unit_types::UnitTypes));
store.register_late_pass(|| Box::new(loops::Loops));
store.register_late_pass(|| Box::new(main_recursion::MainRecursion::default()));
store.register_late_pass(|| Box::new(lifetimes::Lifetimes));
store.register_late_pass(|| Box::new(entry::HashMapPass));
store.register_late_pass(|| Box::new(minmax::MinMaxPass));
store.register_late_pass(|| Box::new(zero_div_zero::ZeroDiv));
store.register_late_pass(|| Box::new(mutex_atomic::Mutex));
store.register_late_pass(|| Box::new(needless_update::NeedlessUpdate));
store.register_late_pass(|| Box::new(needless_borrowed_ref::NeedlessBorrowedRef));
store.register_late_pass(|| Box::new(borrow_deref_ref::BorrowDerefRef));
store.register_late_pass(|| Box::new(no_effect::NoEffect));
store.register_late_pass(|| Box::new(temporary_assignment::TemporaryAssignment));
store.register_late_pass(move || Box::new(transmute::Transmute::new(msrv)));
store.register_late_pass(|_| Box::new(shadow::Shadow::default()));
store.register_late_pass(|_| Box::new(unit_types::UnitTypes));
store.register_late_pass(|_| Box::new(loops::Loops));
store.register_late_pass(|_| Box::new(main_recursion::MainRecursion::default()));
store.register_late_pass(|_| Box::new(lifetimes::Lifetimes));
store.register_late_pass(|_| Box::new(entry::HashMapPass));
store.register_late_pass(|_| Box::new(minmax::MinMaxPass));
store.register_late_pass(|_| Box::new(zero_div_zero::ZeroDiv));
store.register_late_pass(|_| Box::new(mutex_atomic::Mutex));
store.register_late_pass(|_| Box::new(needless_update::NeedlessUpdate));
store.register_late_pass(|_| Box::new(needless_borrowed_ref::NeedlessBorrowedRef));
store.register_late_pass(|_| Box::new(borrow_deref_ref::BorrowDerefRef));
store.register_late_pass(|_| Box::new(no_effect::NoEffect));
store.register_late_pass(|_| Box::new(temporary_assignment::TemporaryAssignment));
store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv)));
let cognitive_complexity_threshold = conf.cognitive_complexity_threshold;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(cognitive_complexity::CognitiveComplexity::new(
cognitive_complexity_threshold,
))
});
let too_large_for_stack = conf.too_large_for_stack;
store.register_late_pass(move || Box::new(escape::BoxedLocal { too_large_for_stack }));
store.register_late_pass(move || Box::new(vec::UselessVec { too_large_for_stack }));
store.register_late_pass(|| Box::new(panic_unimplemented::PanicUnimplemented));
store.register_late_pass(|| Box::new(strings::StringLitAsBytes));
store.register_late_pass(|| Box::new(derive::Derive));
store.register_late_pass(|| Box::new(derivable_impls::DerivableImpls));
store.register_late_pass(|| Box::new(drop_forget_ref::DropForgetRef));
store.register_late_pass(|| Box::new(empty_enum::EmptyEnum));
store.register_late_pass(|| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
store.register_late_pass(|| Box::new(regex::Regex));
store.register_late_pass(|| Box::new(copies::CopyAndPaste));
store.register_late_pass(|| Box::new(copy_iterator::CopyIterator));
store.register_late_pass(|| Box::new(format::UselessFormat));
store.register_late_pass(|| Box::new(swap::Swap));
store.register_late_pass(|| Box::new(overflow_check_conditional::OverflowCheckConditional));
store.register_late_pass(|| Box::new(new_without_default::NewWithoutDefault::default()));
store.register_late_pass(move |_| Box::new(escape::BoxedLocal { too_large_for_stack }));
store.register_late_pass(move |_| Box::new(vec::UselessVec { too_large_for_stack }));
store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
store.register_late_pass(|_| Box::new(strings::StringLitAsBytes));
store.register_late_pass(|_| Box::new(derive::Derive));
store.register_late_pass(|_| Box::new(derivable_impls::DerivableImpls));
store.register_late_pass(|_| Box::new(drop_forget_ref::DropForgetRef));
store.register_late_pass(|_| Box::new(empty_enum::EmptyEnum));
store.register_late_pass(|_| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
store.register_late_pass(|_| Box::new(regex::Regex));
store.register_late_pass(|_| Box::new(copies::CopyAndPaste));
store.register_late_pass(|_| Box::new(copy_iterator::CopyIterator));
store.register_late_pass(|_| Box::new(format::UselessFormat));
store.register_late_pass(|_| Box::new(swap::Swap));
store.register_late_pass(|_| Box::new(overflow_check_conditional::OverflowCheckConditional));
store.register_late_pass(|_| Box::new(new_without_default::NewWithoutDefault::default()));
let disallowed_names = conf.disallowed_names.iter().cloned().collect::<FxHashSet<_>>();
store.register_late_pass(move || Box::new(disallowed_names::DisallowedNames::new(disallowed_names.clone())));
store.register_late_pass(move |_| Box::new(disallowed_names::DisallowedNames::new(disallowed_names.clone())));
let too_many_arguments_threshold = conf.too_many_arguments_threshold;
let too_many_lines_threshold = conf.too_many_lines_threshold;
let large_error_threshold = conf.large_error_threshold;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(functions::Functions::new(
too_many_arguments_threshold,
too_many_lines_threshold,
@ -678,73 +678,73 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
))
});
let doc_valid_idents = conf.doc_valid_idents.iter().cloned().collect::<FxHashSet<_>>();
store.register_late_pass(move || Box::new(doc::DocMarkdown::new(doc_valid_idents.clone())));
store.register_late_pass(|| Box::new(neg_multiply::NegMultiply));
store.register_late_pass(|| Box::new(mem_forget::MemForget));
store.register_late_pass(|| Box::new(let_if_seq::LetIfSeq));
store.register_late_pass(|| Box::new(mixed_read_write_in_expression::EvalOrderDependence));
store.register_late_pass(|| Box::new(missing_doc::MissingDoc::new()));
store.register_late_pass(|| Box::new(missing_inline::MissingInline));
store.register_late_pass(move || Box::new(exhaustive_items::ExhaustiveItems));
store.register_late_pass(|| Box::new(match_result_ok::MatchResultOk));
store.register_late_pass(|| Box::new(partialeq_ne_impl::PartialEqNeImpl));
store.register_late_pass(|| Box::new(unused_io_amount::UnusedIoAmount));
store.register_late_pass(move |_| Box::new(doc::DocMarkdown::new(doc_valid_idents.clone())));
store.register_late_pass(|_| Box::new(neg_multiply::NegMultiply));
store.register_late_pass(|_| Box::new(mem_forget::MemForget));
store.register_late_pass(|_| Box::new(let_if_seq::LetIfSeq));
store.register_late_pass(|_| Box::new(mixed_read_write_in_expression::EvalOrderDependence));
store.register_late_pass(|_| Box::new(missing_doc::MissingDoc::new()));
store.register_late_pass(|_| Box::new(missing_inline::MissingInline));
store.register_late_pass(move |_| Box::new(exhaustive_items::ExhaustiveItems));
store.register_late_pass(|_| Box::new(match_result_ok::MatchResultOk));
store.register_late_pass(|_| Box::new(partialeq_ne_impl::PartialEqNeImpl));
store.register_late_pass(|_| Box::new(unused_io_amount::UnusedIoAmount));
let enum_variant_size_threshold = conf.enum_variant_size_threshold;
store.register_late_pass(move || Box::new(large_enum_variant::LargeEnumVariant::new(enum_variant_size_threshold)));
store.register_late_pass(|| Box::new(explicit_write::ExplicitWrite));
store.register_late_pass(|| Box::new(needless_pass_by_value::NeedlessPassByValue));
store.register_late_pass(move |_| Box::new(large_enum_variant::LargeEnumVariant::new(enum_variant_size_threshold)));
store.register_late_pass(|_| Box::new(explicit_write::ExplicitWrite));
store.register_late_pass(|_| Box::new(needless_pass_by_value::NeedlessPassByValue));
let pass_by_ref_or_value = pass_by_ref_or_value::PassByRefOrValue::new(
conf.trivial_copy_size_limit,
conf.pass_by_value_size_limit,
conf.avoid_breaking_exported_api,
&sess.target,
);
store.register_late_pass(move || Box::new(pass_by_ref_or_value));
store.register_late_pass(|| Box::new(ref_option_ref::RefOptionRef));
store.register_late_pass(|| Box::new(infinite_iter::InfiniteIter));
store.register_late_pass(|| Box::new(inline_fn_without_body::InlineFnWithoutBody));
store.register_late_pass(|| Box::new(useless_conversion::UselessConversion::default()));
store.register_late_pass(|| Box::new(implicit_hasher::ImplicitHasher));
store.register_late_pass(|| Box::new(fallible_impl_from::FallibleImplFrom));
store.register_late_pass(|| Box::new(question_mark::QuestionMark));
store.register_late_pass(move |_| Box::new(pass_by_ref_or_value));
store.register_late_pass(|_| Box::new(ref_option_ref::RefOptionRef));
store.register_late_pass(|_| Box::new(infinite_iter::InfiniteIter));
store.register_late_pass(|_| Box::new(inline_fn_without_body::InlineFnWithoutBody));
store.register_late_pass(|_| Box::new(useless_conversion::UselessConversion::default()));
store.register_late_pass(|_| Box::new(implicit_hasher::ImplicitHasher));
store.register_late_pass(|_| Box::new(fallible_impl_from::FallibleImplFrom));
store.register_late_pass(|_| Box::new(question_mark::QuestionMark));
store.register_early_pass(|| Box::new(suspicious_operation_groupings::SuspiciousOperationGroupings));
store.register_late_pass(|| Box::new(suspicious_trait_impl::SuspiciousImpl));
store.register_late_pass(|| Box::new(map_unit_fn::MapUnit));
store.register_late_pass(|| Box::new(inherent_impl::MultipleInherentImpl));
store.register_late_pass(|| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd));
store.register_late_pass(|| Box::new(unwrap::Unwrap));
store.register_late_pass(|| Box::new(indexing_slicing::IndexingSlicing));
store.register_late_pass(|| Box::new(non_copy_const::NonCopyConst));
store.register_late_pass(|| Box::new(ptr_offset_with_cast::PtrOffsetWithCast));
store.register_late_pass(|| Box::new(redundant_clone::RedundantClone));
store.register_late_pass(|| Box::new(slow_vector_initialization::SlowVectorInit));
store.register_late_pass(move || Box::new(unnecessary_wraps::UnnecessaryWraps::new(avoid_breaking_exported_api)));
store.register_late_pass(|| Box::new(assertions_on_constants::AssertionsOnConstants));
store.register_late_pass(|| Box::new(assertions_on_result_states::AssertionsOnResultStates));
store.register_late_pass(|| Box::new(inherent_to_string::InherentToString));
store.register_late_pass(|_| Box::new(suspicious_trait_impl::SuspiciousImpl));
store.register_late_pass(|_| Box::new(map_unit_fn::MapUnit));
store.register_late_pass(|_| Box::new(inherent_impl::MultipleInherentImpl));
store.register_late_pass(|_| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd));
store.register_late_pass(|_| Box::new(unwrap::Unwrap));
store.register_late_pass(|_| Box::new(indexing_slicing::IndexingSlicing));
store.register_late_pass(|_| Box::new(non_copy_const::NonCopyConst));
store.register_late_pass(|_| Box::new(ptr_offset_with_cast::PtrOffsetWithCast));
store.register_late_pass(|_| Box::new(redundant_clone::RedundantClone));
store.register_late_pass(|_| Box::new(slow_vector_initialization::SlowVectorInit));
store.register_late_pass(move |_| Box::new(unnecessary_wraps::UnnecessaryWraps::new(avoid_breaking_exported_api)));
store.register_late_pass(|_| Box::new(assertions_on_constants::AssertionsOnConstants));
store.register_late_pass(|_| Box::new(assertions_on_result_states::AssertionsOnResultStates));
store.register_late_pass(|_| Box::new(inherent_to_string::InherentToString));
let max_trait_bounds = conf.max_trait_bounds;
store.register_late_pass(move || Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
store.register_late_pass(|| Box::new(comparison_chain::ComparisonChain));
store.register_late_pass(|| Box::new(mut_key::MutableKeyType));
store.register_late_pass(move |_| Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
store.register_late_pass(|_| Box::new(comparison_chain::ComparisonChain));
store.register_late_pass(|_| Box::new(mut_key::MutableKeyType));
store.register_early_pass(|| Box::new(reference::DerefAddrOf));
store.register_early_pass(|| Box::new(double_parens::DoubleParens));
store.register_late_pass(|| Box::new(format_impl::FormatImpl::new()));
store.register_late_pass(|_| Box::new(format_impl::FormatImpl::new()));
store.register_early_pass(|| Box::new(unsafe_removed_from_name::UnsafeNameRemoval));
store.register_early_pass(|| Box::new(else_if_without_else::ElseIfWithoutElse));
store.register_early_pass(|| Box::new(int_plus_one::IntPlusOne));
store.register_early_pass(|| Box::new(formatting::Formatting));
store.register_early_pass(|| Box::new(misc_early::MiscEarlyLints));
store.register_early_pass(|| Box::new(redundant_closure_call::RedundantClosureCall));
store.register_late_pass(|| Box::new(redundant_closure_call::RedundantClosureCall));
store.register_late_pass(|_| Box::new(redundant_closure_call::RedundantClosureCall));
store.register_early_pass(|| Box::new(unused_unit::UnusedUnit));
store.register_late_pass(|| Box::new(returns::Return));
store.register_late_pass(|_| Box::new(returns::Return));
store.register_early_pass(|| Box::new(collapsible_if::CollapsibleIf));
store.register_early_pass(|| Box::new(items_after_statements::ItemsAfterStatements));
store.register_early_pass(|| Box::new(precedence::Precedence));
store.register_late_pass(|| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));
store.register_late_pass(|_| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));
store.register_early_pass(|| Box::new(needless_continue::NeedlessContinue));
store.register_early_pass(|| Box::new(redundant_else::RedundantElse));
store.register_late_pass(|| Box::new(create_dir::CreateDir));
store.register_late_pass(|_| Box::new(create_dir::CreateDir));
store.register_early_pass(|| Box::new(needless_arbitrary_self_type::NeedlessArbitrarySelfType));
let literal_representation_lint_fraction_readability = conf.unreadable_literal_lint_fractions;
store.register_early_pass(move || {
@ -759,7 +759,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
))
});
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(enum_variants::EnumVariantNames::new(
enum_variant_name_threshold,
avoid_breaking_exported_api,
@ -767,23 +767,23 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments));
let upper_case_acronyms_aggressive = conf.upper_case_acronyms_aggressive;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(upper_case_acronyms::UpperCaseAcronyms::new(
avoid_breaking_exported_api,
upper_case_acronyms_aggressive,
))
});
store.register_late_pass(|| Box::new(default::Default::default()));
store.register_late_pass(move || Box::new(unused_self::UnusedSelf::new(avoid_breaking_exported_api)));
store.register_late_pass(|| Box::new(mutable_debug_assertion::DebugAssertWithMutCall));
store.register_late_pass(|| Box::new(exit::Exit));
store.register_late_pass(|| Box::new(to_digit_is_some::ToDigitIsSome));
store.register_late_pass(|_| Box::new(default::Default::default()));
store.register_late_pass(move |_| Box::new(unused_self::UnusedSelf::new(avoid_breaking_exported_api)));
store.register_late_pass(|_| Box::new(mutable_debug_assertion::DebugAssertWithMutCall));
store.register_late_pass(|_| Box::new(exit::Exit));
store.register_late_pass(|_| Box::new(to_digit_is_some::ToDigitIsSome));
let array_size_threshold = conf.array_size_threshold;
store.register_late_pass(move || Box::new(large_stack_arrays::LargeStackArrays::new(array_size_threshold)));
store.register_late_pass(move || Box::new(large_const_arrays::LargeConstArrays::new(array_size_threshold)));
store.register_late_pass(|| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
store.register_late_pass(move |_| Box::new(large_stack_arrays::LargeStackArrays::new(array_size_threshold)));
store.register_late_pass(move |_| Box::new(large_const_arrays::LargeConstArrays::new(array_size_threshold)));
store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
store.register_early_pass(|| Box::new(as_conversions::AsConversions));
store.register_late_pass(|| Box::new(let_underscore::LetUnderscore));
store.register_late_pass(|_| Box::new(let_underscore::LetUnderscore));
store.register_early_pass(|| Box::new(single_component_path_imports::SingleComponentPathImports));
let max_fn_params_bools = conf.max_fn_params_bools;
let max_struct_bools = conf.max_struct_bools;
@ -795,17 +795,17 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
let warn_on_all_wildcard_imports = conf.warn_on_all_wildcard_imports;
store.register_late_pass(move || Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
store.register_late_pass(|| Box::new(redundant_pub_crate::RedundantPubCrate::default()));
store.register_late_pass(|| Box::new(unnamed_address::UnnamedAddress));
store.register_late_pass(move || Box::new(dereference::Dereferencing::new(msrv)));
store.register_late_pass(|| Box::new(option_if_let_else::OptionIfLetElse));
store.register_late_pass(|| Box::new(future_not_send::FutureNotSend));
store.register_late_pass(|| Box::new(if_let_mutex::IfLetMutex));
store.register_late_pass(|| Box::new(if_not_else::IfNotElse));
store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn));
store.register_late_pass(|| Box::new(panic_in_result_fn::PanicInResultFn));
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
store.register_late_pass(|_| Box::new(redundant_pub_crate::RedundantPubCrate::default()));
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv)));
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
store.register_late_pass(|_| Box::new(if_let_mutex::IfLetMutex));
store.register_late_pass(|_| Box::new(if_not_else::IfNotElse));
store.register_late_pass(|_| Box::new(equatable_if_let::PatternEquality));
store.register_late_pass(|_| Box::new(manual_async_fn::ManualAsyncFn));
store.register_late_pass(|_| Box::new(panic_in_result_fn::PanicInResultFn));
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
store.register_early_pass(move || {
Box::new(non_expressive_names::NonExpressiveNames {
@ -814,92 +814,92 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
let macro_matcher = conf.standard_macro_braces.iter().cloned().collect::<FxHashSet<_>>();
store.register_early_pass(move || Box::new(nonstandard_macro_braces::MacroBraces::new(&macro_matcher)));
store.register_late_pass(|| Box::new(macro_use::MacroUseImports::default()));
store.register_late_pass(|| Box::new(pattern_type_mismatch::PatternTypeMismatch));
store.register_late_pass(|| Box::new(unwrap_in_result::UnwrapInResult));
store.register_late_pass(|| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
store.register_late_pass(|| Box::new(async_yields_async::AsyncYieldsAsync));
store.register_late_pass(|_| Box::new(macro_use::MacroUseImports::default()));
store.register_late_pass(|_| Box::new(pattern_type_mismatch::PatternTypeMismatch));
store.register_late_pass(|_| Box::new(unwrap_in_result::UnwrapInResult));
store.register_late_pass(|_| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
store.register_late_pass(|_| Box::new(async_yields_async::AsyncYieldsAsync));
let disallowed_methods = conf.disallowed_methods.clone();
store.register_late_pass(move || Box::new(disallowed_methods::DisallowedMethods::new(disallowed_methods.clone())));
store.register_late_pass(move |_| Box::new(disallowed_methods::DisallowedMethods::new(disallowed_methods.clone())));
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86AttSyntax));
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
store.register_late_pass(|| Box::new(empty_drop::EmptyDrop));
store.register_late_pass(|| Box::new(strings::StrToString));
store.register_late_pass(|| Box::new(strings::StringToString));
store.register_late_pass(|| Box::new(zero_sized_map_values::ZeroSizedMapValues));
store.register_late_pass(|| Box::new(vec_init_then_push::VecInitThenPush::default()));
store.register_late_pass(|| Box::new(redundant_slicing::RedundantSlicing));
store.register_late_pass(|| Box::new(from_str_radix_10::FromStrRadix10));
store.register_late_pass(move || Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv)));
store.register_late_pass(|| Box::new(bool_assert_comparison::BoolAssertComparison));
store.register_late_pass(|_| Box::new(empty_drop::EmptyDrop));
store.register_late_pass(|_| Box::new(strings::StrToString));
store.register_late_pass(|_| Box::new(strings::StringToString));
store.register_late_pass(|_| Box::new(zero_sized_map_values::ZeroSizedMapValues));
store.register_late_pass(|_| Box::new(vec_init_then_push::VecInitThenPush::default()));
store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));
store.register_late_pass(|_| Box::new(from_str_radix_10::FromStrRadix10));
store.register_late_pass(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv)));
store.register_late_pass(|_| Box::new(bool_assert_comparison::BoolAssertComparison));
store.register_early_pass(move || Box::new(module_style::ModStyle));
store.register_late_pass(|| Box::new(unused_async::UnusedAsync));
store.register_late_pass(|_| Box::new(unused_async::UnusedAsync));
let disallowed_types = conf.disallowed_types.clone();
store.register_late_pass(move || Box::new(disallowed_types::DisallowedTypes::new(disallowed_types.clone())));
store.register_late_pass(move |_| Box::new(disallowed_types::DisallowedTypes::new(disallowed_types.clone())));
let import_renames = conf.enforced_import_renames.clone();
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(missing_enforced_import_rename::ImportRename::new(
import_renames.clone(),
))
});
let scripts = conf.allowed_scripts.clone();
store.register_early_pass(move || Box::new(disallowed_script_idents::DisallowedScriptIdents::new(&scripts)));
store.register_late_pass(|| Box::new(strlen_on_c_strings::StrlenOnCStrings));
store.register_late_pass(move || Box::new(self_named_constructors::SelfNamedConstructors));
store.register_late_pass(move || Box::new(iter_not_returning_iterator::IterNotReturningIterator));
store.register_late_pass(move || Box::new(manual_assert::ManualAssert));
store.register_late_pass(|_| Box::new(strlen_on_c_strings::StrlenOnCStrings));
store.register_late_pass(move |_| Box::new(self_named_constructors::SelfNamedConstructors));
store.register_late_pass(move |_| Box::new(iter_not_returning_iterator::IterNotReturningIterator));
store.register_late_pass(move |_| Box::new(manual_assert::ManualAssert));
let enable_raw_pointer_heuristic_for_send = conf.enable_raw_pointer_heuristic_for_send;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(non_send_fields_in_send_ty::NonSendFieldInSendTy::new(
enable_raw_pointer_heuristic_for_send,
))
});
store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
store.register_late_pass(move || Box::new(format_args::FormatArgs));
store.register_late_pass(|| Box::new(trailing_empty_array::TrailingEmptyArray));
store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
store.register_late_pass(move |_| Box::new(format_args::FormatArgs));
store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
store.register_late_pass(|| Box::new(needless_late_init::NeedlessLateInit));
store.register_late_pass(|| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
store.register_late_pass(|| Box::new(init_numbered_fields::NumberedFields));
store.register_late_pass(|_| Box::new(needless_late_init::NeedlessLateInit));
store.register_late_pass(|_| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
store.register_late_pass(|_| Box::new(init_numbered_fields::NumberedFields));
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
store.register_late_pass(move || Box::new(manual_bits::ManualBits::new(msrv)));
store.register_late_pass(|| Box::new(default_union_representation::DefaultUnionRepresentation));
store.register_late_pass(move |_| Box::new(manual_bits::ManualBits::new(msrv)));
store.register_late_pass(|_| Box::new(default_union_representation::DefaultUnionRepresentation));
store.register_early_pass(|| Box::new(doc_link_with_quotes::DocLinkWithQuotes));
store.register_late_pass(|| Box::new(only_used_in_recursion::OnlyUsedInRecursion::default()));
store.register_late_pass(|_| Box::new(only_used_in_recursion::OnlyUsedInRecursion::default()));
let allow_dbg_in_tests = conf.allow_dbg_in_tests;
store.register_late_pass(move || Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
store.register_late_pass(move |_| Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
let cargo_ignore_publish = conf.cargo_ignore_publish;
store.register_late_pass(move || {
store.register_late_pass(move |_| {
Box::new(cargo::Cargo {
ignore_publish: cargo_ignore_publish,
})
});
store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets));
store.register_late_pass(|| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings));
store.register_late_pass(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings));
store.register_early_pass(|| Box::new(pub_use::PubUse));
store.register_late_pass(|| Box::new(format_push_string::FormatPushString));
store.register_late_pass(|_| Box::new(format_push_string::FormatPushString));
let max_include_file_size = conf.max_include_file_size;
store.register_late_pass(move || Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
store.register_late_pass(|| Box::new(strings::TrimSplitWhitespace));
store.register_late_pass(|| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
store.register_late_pass(move |_| Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
store.register_late_pass(|_| Box::new(strings::TrimSplitWhitespace));
store.register_late_pass(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
store.register_early_pass(|| Box::new(duplicate_mod::DuplicateMod::default()));
store.register_early_pass(|| Box::new(unused_rounding::UnusedRounding));
store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv)));
store.register_late_pass(|| Box::new(swap_ptr_to_ref::SwapPtrToRef));
store.register_late_pass(|| Box::new(mismatching_type_param_order::TypeParamMismatch));
store.register_late_pass(|| Box::new(read_zero_byte_vec::ReadZeroByteVec));
store.register_late_pass(|| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
store.register_late_pass(move || Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
store.register_late_pass(move || Box::new(manual_retain::ManualRetain::new(msrv)));
store.register_late_pass(|_| Box::new(swap_ptr_to_ref::SwapPtrToRef));
store.register_late_pass(|_| Box::new(mismatching_type_param_order::TypeParamMismatch));
store.register_late_pass(|_| Box::new(read_zero_byte_vec::ReadZeroByteVec));
store.register_late_pass(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv)));
let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold;
store.register_late_pass(move || Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
store.register_late_pass(|| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
store.register_late_pass(|| Box::new(std_instead_of_core::StdReexports::default()));
store.register_late_pass(|| Box::new(manual_instant_elapsed::ManualInstantElapsed));
store.register_late_pass(|| Box::new(partialeq_to_none::PartialeqToNone));
store.register_late_pass(|| Box::new(manual_string_new::ManualStringNew));
store.register_late_pass(|| Box::new(unused_peekable::UnusedPeekable));
store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
store.register_late_pass(|_| Box::new(std_instead_of_core::StdReexports::default()));
store.register_late_pass(|_| Box::new(manual_instant_elapsed::ManualInstantElapsed));
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
store.register_late_pass(|_| Box::new(manual_string_new::ManualStringNew));
store.register_late_pass(|_| Box::new(unused_peekable::UnusedPeekable));
store.register_early_pass(|| Box::new(multi_assignments::MultiAssignments));
// add lints here, do not remove this comment, it's used in `new_lint`
}