mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-09 05:23:07 +00:00
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:
commit
87788097b7
@ -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.
|
||||
|
@ -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> {
|
||||
|
@ -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".)
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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).
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
@ -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),
|
||||
|
@ -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.
|
||||
|
@ -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>>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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> {
|
||||
|
@ -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! {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
| +
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
10
src/test/ui/parser/issue-101477-enum.fixed
Normal file
10
src/test/ui/parser/issue-101477-enum.fixed
Normal file
@ -0,0 +1,10 @@
|
||||
// run-rustfix
|
||||
|
||||
#[allow(dead_code)]
|
||||
enum Demo {
|
||||
A = 1,
|
||||
B = 2 //~ ERROR unexpected `==`
|
||||
//~^ expected item, found `==`
|
||||
}
|
||||
|
||||
fn main() {}
|
10
src/test/ui/parser/issue-101477-enum.rs
Normal file
10
src/test/ui/parser/issue-101477-enum.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// run-rustfix
|
||||
|
||||
#[allow(dead_code)]
|
||||
enum Demo {
|
||||
A = 1,
|
||||
B == 2 //~ ERROR unexpected `==`
|
||||
//~^ expected item, found `==`
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/parser/issue-101477-enum.stderr
Normal file
14
src/test/ui/parser/issue-101477-enum.stderr
Normal 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
|
||||
|
6
src/test/ui/parser/issue-101477-let.fixed
Normal file
6
src/test/ui/parser/issue-101477-let.fixed
Normal file
@ -0,0 +1,6 @@
|
||||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
let x = 2; //~ ERROR unexpected `==`
|
||||
println!("x: {}", x)
|
||||
}
|
6
src/test/ui/parser/issue-101477-let.rs
Normal file
6
src/test/ui/parser/issue-101477-let.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
let x == 2; //~ ERROR unexpected `==`
|
||||
println!("x: {}", x)
|
||||
}
|
8
src/test/ui/parser/issue-101477-let.stderr
Normal file
8
src/test/ui/parser/issue-101477-let.stderr
Normal 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
|
||||
|
@ -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`
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
12
src/test/ui/suggestions/restrict-type-not-param.rs
Normal file
12
src/test/ui/suggestions/restrict-type-not-param.rs
Normal 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() {}
|
26
src/test/ui/suggestions/restrict-type-not-param.stderr
Normal file
26
src/test/ui/suggestions/restrict-type-not-param.stderr
Normal 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`.
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
58
src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
Normal file
58
src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
Normal 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`.
|
@ -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());
|
||||
}
|
@ -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`.
|
@ -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;
|
||||
| +
|
||||
|
@ -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;
|
||||
| +
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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(¯o_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`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user