Auto merge of #136448 - matthiaskrgr:rollup-pdim5di, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #134272 (Remove rustc_encodable_decodable feature) - #136283 (Update encode_utf16 to mention it is native endian) - #136394 (Clean up MonoItem::instantiation_mode) - #136402 (diagnostics: fix borrowck suggestions for if/while let conditionals) - #136415 (Highlight clarifying information in "expected/found" error) - #136422 (Convert two `rustc_middle::lint` functions to `Span` methods.) - #136434 (rustc_allowed_through_unstable_modules: require deprecation message) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4a43094662
143 changed files with 774 additions and 1179 deletions
|
@ -101,16 +101,6 @@ impl PartialConstStability {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
|
||||||
#[derive(HashStable_Generic)]
|
|
||||||
pub enum AllowedThroughUnstableModules {
|
|
||||||
/// This does not get a deprecation warning. We still generally would prefer people to use the
|
|
||||||
/// fully stable path, and a warning will likely be emitted in the future.
|
|
||||||
WithoutDeprecation,
|
|
||||||
/// Emit the given deprecation warning.
|
|
||||||
WithDeprecation(Symbol),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The available stability levels.
|
/// The available stability levels.
|
||||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
|
@ -147,8 +137,9 @@ pub enum StabilityLevel {
|
||||||
Stable {
|
Stable {
|
||||||
/// Rust release which stabilized this feature.
|
/// Rust release which stabilized this feature.
|
||||||
since: StableSince,
|
since: StableSince,
|
||||||
/// This is `Some` if this item allowed to be referred to on stable via unstable modules.
|
/// This is `Some` if this item allowed to be referred to on stable via unstable modules;
|
||||||
allowed_through_unstable_modules: Option<AllowedThroughUnstableModules>,
|
/// the `Symbol` is the deprecation message printed in that case.
|
||||||
|
allowed_through_unstable_modules: Option<Symbol>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ use rustc_ast::MetaItem;
|
||||||
use rustc_ast::attr::AttributeExt;
|
use rustc_ast::attr::AttributeExt;
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_attr_data_structures::{
|
use rustc_attr_data_structures::{
|
||||||
AllowedThroughUnstableModules, ConstStability, DefaultBodyStability, Stability, StabilityLevel,
|
ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, UnstableReason,
|
||||||
StableSince, UnstableReason, VERSION_PLACEHOLDER,
|
VERSION_PLACEHOLDER,
|
||||||
};
|
};
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::{Span, Symbol, sym};
|
use rustc_span::{Span, Symbol, kw, sym};
|
||||||
|
|
||||||
use crate::attributes::util::UnsupportedLiteralReason;
|
use crate::attributes::util::UnsupportedLiteralReason;
|
||||||
use crate::{parse_version, session_diagnostics};
|
use crate::{parse_version, session_diagnostics};
|
||||||
|
@ -29,10 +29,14 @@ pub fn find_stability(
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
match attr.name_or_empty() {
|
match attr.name_or_empty() {
|
||||||
sym::rustc_allowed_through_unstable_modules => {
|
sym::rustc_allowed_through_unstable_modules => {
|
||||||
allowed_through_unstable_modules = Some(match attr.value_str() {
|
// The value is mandatory, but avoid ICEs in case such code reaches this function.
|
||||||
Some(msg) => AllowedThroughUnstableModules::WithDeprecation(msg),
|
allowed_through_unstable_modules = Some(attr.value_str().unwrap_or_else(|| {
|
||||||
None => AllowedThroughUnstableModules::WithoutDeprecation,
|
sess.dcx().span_delayed_bug(
|
||||||
})
|
item_sp,
|
||||||
|
"`#[rustc_allowed_through_unstable_modules]` without deprecation message",
|
||||||
|
);
|
||||||
|
kw::Empty
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
sym::unstable => {
|
sym::unstable => {
|
||||||
if stab.is_some() {
|
if stab.is_some() {
|
||||||
|
|
|
@ -248,7 +248,98 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
);
|
);
|
||||||
err.span_label(body.source_info(drop_loc).span, message);
|
err.span_label(body.source_info(drop_loc).span, message);
|
||||||
|
|
||||||
if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
|
struct FindLetExpr<'hir> {
|
||||||
|
span: Span,
|
||||||
|
result: Option<(Span, &'hir hir::Pat<'hir>, &'hir hir::Expr<'hir>)>,
|
||||||
|
tcx: TyCtxt<'hir>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'hir> rustc_hir::intravisit::Visitor<'hir> for FindLetExpr<'hir> {
|
||||||
|
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
|
||||||
|
fn nested_visit_map(&mut self) -> Self::Map {
|
||||||
|
self.tcx.hir()
|
||||||
|
}
|
||||||
|
fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
|
||||||
|
if let hir::ExprKind::If(cond, _conseq, _alt)
|
||||||
|
| hir::ExprKind::Loop(
|
||||||
|
hir::Block {
|
||||||
|
expr:
|
||||||
|
Some(&hir::Expr {
|
||||||
|
kind: hir::ExprKind::If(cond, _conseq, _alt),
|
||||||
|
..
|
||||||
|
}),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
hir::LoopSource::While,
|
||||||
|
_,
|
||||||
|
) = expr.kind
|
||||||
|
&& let hir::ExprKind::Let(hir::LetExpr {
|
||||||
|
init: let_expr_init,
|
||||||
|
span: let_expr_span,
|
||||||
|
pat: let_expr_pat,
|
||||||
|
..
|
||||||
|
}) = cond.kind
|
||||||
|
&& let_expr_init.span.contains(self.span)
|
||||||
|
{
|
||||||
|
self.result =
|
||||||
|
Some((*let_expr_span, let_expr_pat, let_expr_init))
|
||||||
|
} else {
|
||||||
|
hir::intravisit::walk_expr(self, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
|
||||||
|
&& let hir::Node::Expr(expr) = tcx.hir_node(if_then)
|
||||||
|
&& let hir::ExprKind::If(cond, conseq, alt) = expr.kind
|
||||||
|
&& let hir::ExprKind::Let(&hir::LetExpr {
|
||||||
|
span: _,
|
||||||
|
pat,
|
||||||
|
init,
|
||||||
|
// FIXME(#101728): enable rewrite when type ascription is
|
||||||
|
// stabilized again.
|
||||||
|
ty: None,
|
||||||
|
recovered: _,
|
||||||
|
}) = cond.kind
|
||||||
|
&& pat.span.can_be_used_for_suggestions()
|
||||||
|
&& let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
|
||||||
|
{
|
||||||
|
suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
|
||||||
|
} else if let Some((old, new)) = multiple_borrow_span
|
||||||
|
&& let def_id = body.source.def_id()
|
||||||
|
&& let Some(node) = tcx.hir().get_if_local(def_id)
|
||||||
|
&& let Some(body_id) = node.body_id()
|
||||||
|
&& let hir_body = tcx.hir().body(body_id)
|
||||||
|
&& let mut expr_finder = (FindLetExpr { span: old, result: None, tcx })
|
||||||
|
&& let Some((let_expr_span, let_expr_pat, let_expr_init)) = {
|
||||||
|
expr_finder.visit_expr(hir_body.value);
|
||||||
|
expr_finder.result
|
||||||
|
}
|
||||||
|
&& !let_expr_span.contains(new)
|
||||||
|
{
|
||||||
|
// #133941: The `old` expression is at the conditional part of an
|
||||||
|
// if/while let expression. Adding a semicolon won't work.
|
||||||
|
// Instead, try suggesting the `matches!` macro or a temporary.
|
||||||
|
if let_expr_pat
|
||||||
|
.walk_short(|pat| !matches!(pat.kind, hir::PatKind::Binding(..)))
|
||||||
|
{
|
||||||
|
if let Ok(pat_snippet) =
|
||||||
|
tcx.sess.source_map().span_to_snippet(let_expr_pat.span)
|
||||||
|
&& let Ok(init_snippet) =
|
||||||
|
tcx.sess.source_map().span_to_snippet(let_expr_init.span)
|
||||||
|
{
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
let_expr_span,
|
||||||
|
"consider using the `matches!` macro",
|
||||||
|
format!("matches!({init_snippet}, {pat_snippet})"),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
err.note("consider using the `matches!` macro");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
|
||||||
if info.tail_result_is_ignored {
|
if info.tail_result_is_ignored {
|
||||||
// #85581: If the first mutable borrow's scope contains
|
// #85581: If the first mutable borrow's scope contains
|
||||||
// the second borrow, this suggestion isn't helpful.
|
// the second borrow, this suggestion isn't helpful.
|
||||||
|
@ -281,23 +372,6 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
} else if let &LocalInfo::IfThenRescopeTemp { if_then } =
|
|
||||||
local_decl.local_info()
|
|
||||||
&& let hir::Node::Expr(expr) = tcx.hir_node(if_then)
|
|
||||||
&& let hir::ExprKind::If(cond, conseq, alt) = expr.kind
|
|
||||||
&& let hir::ExprKind::Let(&hir::LetExpr {
|
|
||||||
span: _,
|
|
||||||
pat,
|
|
||||||
init,
|
|
||||||
// FIXME(#101728): enable rewrite when type ascription is
|
|
||||||
// stabilized again.
|
|
||||||
ty: None,
|
|
||||||
recovered: _,
|
|
||||||
}) = cond.kind
|
|
||||||
&& pat.span.can_be_used_for_suggestions()
|
|
||||||
&& let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
|
|
||||||
{
|
|
||||||
suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
|
||||||
|
|
||||||
let (ident, vdata, fields) = match substr.fields {
|
let (ident, vdata, fields) = match substr.fields {
|
||||||
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
|
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
|
||||||
EnumMatching(_, v, fields) => (v.ident, &v.data, fields),
|
EnumMatching(v, fields) => (v.ident, &v.data, fields),
|
||||||
AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr),
|
AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr),
|
||||||
EnumDiscr(..) | StaticStruct(..) | StaticEnum(..) => {
|
EnumDiscr(..) | StaticStruct(..) | StaticEnum(..) => {
|
||||||
cx.dcx().span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
|
cx.dcx().span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
|
||||||
|
|
|
@ -1,215 +0,0 @@
|
||||||
//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
|
|
||||||
|
|
||||||
use rustc_ast::ptr::P;
|
|
||||||
use rustc_ast::{self as ast, Expr, MetaItem, Mutability};
|
|
||||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
|
||||||
use rustc_span::{Ident, Span, Symbol, sym};
|
|
||||||
use thin_vec::{ThinVec, thin_vec};
|
|
||||||
|
|
||||||
use crate::deriving::generic::ty::*;
|
|
||||||
use crate::deriving::generic::*;
|
|
||||||
use crate::deriving::pathvec_std;
|
|
||||||
|
|
||||||
pub(crate) fn expand_deriving_rustc_decodable(
|
|
||||||
cx: &ExtCtxt<'_>,
|
|
||||||
span: Span,
|
|
||||||
mitem: &MetaItem,
|
|
||||||
item: &Annotatable,
|
|
||||||
push: &mut dyn FnMut(Annotatable),
|
|
||||||
is_const: bool,
|
|
||||||
) {
|
|
||||||
let krate = sym::rustc_serialize;
|
|
||||||
let typaram = sym::__D;
|
|
||||||
|
|
||||||
let trait_def = TraitDef {
|
|
||||||
span,
|
|
||||||
path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
|
|
||||||
skip_path_as_bound: false,
|
|
||||||
needs_copy_as_bound_if_packed: true,
|
|
||||||
additional_bounds: Vec::new(),
|
|
||||||
supports_unions: false,
|
|
||||||
methods: vec![MethodDef {
|
|
||||||
name: sym::decode,
|
|
||||||
generics: Bounds {
|
|
||||||
bounds: vec![(typaram, vec![Path::new_(
|
|
||||||
vec![krate, sym::Decoder],
|
|
||||||
vec![],
|
|
||||||
PathKind::Global,
|
|
||||||
)])],
|
|
||||||
},
|
|
||||||
explicit_self: false,
|
|
||||||
nonself_args: vec![(
|
|
||||||
Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
|
|
||||||
sym::d,
|
|
||||||
)],
|
|
||||||
ret_ty: Path(Path::new_(
|
|
||||||
pathvec_std!(result::Result),
|
|
||||||
vec![
|
|
||||||
Box::new(Self_),
|
|
||||||
Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))),
|
|
||||||
],
|
|
||||||
PathKind::Std,
|
|
||||||
)),
|
|
||||||
attributes: ast::AttrVec::new(),
|
|
||||||
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
|
|
||||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
|
||||||
decodable_substructure(a, b, c, krate)
|
|
||||||
})),
|
|
||||||
}],
|
|
||||||
associated_types: Vec::new(),
|
|
||||||
is_const,
|
|
||||||
};
|
|
||||||
|
|
||||||
trait_def.expand(cx, mitem, item, push)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decodable_substructure(
|
|
||||||
cx: &ExtCtxt<'_>,
|
|
||||||
trait_span: Span,
|
|
||||||
substr: &Substructure<'_>,
|
|
||||||
krate: Symbol,
|
|
||||||
) -> BlockOrExpr {
|
|
||||||
let decoder = substr.nonselflike_args[0].clone();
|
|
||||||
let recurse = vec![
|
|
||||||
Ident::new(krate, trait_span),
|
|
||||||
Ident::new(sym::Decodable, trait_span),
|
|
||||||
Ident::new(sym::decode, trait_span),
|
|
||||||
];
|
|
||||||
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
|
|
||||||
// throw an underscore in front to suppress unused variable warnings
|
|
||||||
let blkarg = Ident::new(sym::_d, trait_span);
|
|
||||||
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
|
||||||
|
|
||||||
let expr = match substr.fields {
|
|
||||||
StaticStruct(_, summary) => {
|
|
||||||
let nfields = match summary {
|
|
||||||
Unnamed(fields, _) => fields.len(),
|
|
||||||
Named(fields) => fields.len(),
|
|
||||||
};
|
|
||||||
let fn_read_struct_field_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
|
|
||||||
|
|
||||||
let path = cx.path_ident(trait_span, substr.type_ident);
|
|
||||||
let result =
|
|
||||||
decode_static_fields(cx, trait_span, path, summary, |cx, span, name, field| {
|
|
||||||
cx.expr_try(
|
|
||||||
span,
|
|
||||||
cx.expr_call_global(span, fn_read_struct_field_path.clone(), thin_vec![
|
|
||||||
blkdecoder.clone(),
|
|
||||||
cx.expr_str(span, name),
|
|
||||||
cx.expr_usize(span, field),
|
|
||||||
exprdecode.clone(),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
let result = cx.expr_ok(trait_span, result);
|
|
||||||
let fn_read_struct_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct]);
|
|
||||||
|
|
||||||
cx.expr_call_global(trait_span, fn_read_struct_path, thin_vec![
|
|
||||||
decoder,
|
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
|
||||||
cx.expr_usize(trait_span, nfields),
|
|
||||||
cx.lambda1(trait_span, result, blkarg),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
StaticEnum(_, fields) => {
|
|
||||||
let variant = Ident::new(sym::i, trait_span);
|
|
||||||
|
|
||||||
let mut arms = ThinVec::with_capacity(fields.len() + 1);
|
|
||||||
let mut variants = ThinVec::with_capacity(fields.len());
|
|
||||||
|
|
||||||
let fn_read_enum_variant_arg_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant_arg]);
|
|
||||||
|
|
||||||
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
|
|
||||||
variants.push(cx.expr_str(v_span, ident.name));
|
|
||||||
|
|
||||||
let path = cx.path(trait_span, vec![substr.type_ident, ident]);
|
|
||||||
let decoded =
|
|
||||||
decode_static_fields(cx, v_span, path, parts, |cx, span, _, field| {
|
|
||||||
let idx = cx.expr_usize(span, field);
|
|
||||||
cx.expr_try(
|
|
||||||
span,
|
|
||||||
cx.expr_call_global(
|
|
||||||
span,
|
|
||||||
fn_read_enum_variant_arg_path.clone(),
|
|
||||||
thin_vec![blkdecoder.clone(), idx, exprdecode.clone()],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
arms.push(cx.arm(v_span, cx.pat_lit(v_span, cx.expr_usize(v_span, i)), decoded));
|
|
||||||
}
|
|
||||||
|
|
||||||
arms.push(cx.arm_unreachable(trait_span));
|
|
||||||
|
|
||||||
let result = cx.expr_ok(
|
|
||||||
trait_span,
|
|
||||||
cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms),
|
|
||||||
);
|
|
||||||
let lambda = cx.lambda(trait_span, vec![blkarg, variant], result);
|
|
||||||
let variant_array_ref = cx.expr_array_ref(trait_span, variants);
|
|
||||||
let fn_read_enum_variant_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant]);
|
|
||||||
let result = cx.expr_call_global(trait_span, fn_read_enum_variant_path, thin_vec![
|
|
||||||
blkdecoder,
|
|
||||||
variant_array_ref,
|
|
||||||
lambda
|
|
||||||
]);
|
|
||||||
let fn_read_enum_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum]);
|
|
||||||
|
|
||||||
cx.expr_call_global(trait_span, fn_read_enum_path, thin_vec![
|
|
||||||
decoder,
|
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
|
||||||
cx.lambda1(trait_span, result, blkarg),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
_ => cx.dcx().bug("expected StaticEnum or StaticStruct in derive(Decodable)"),
|
|
||||||
};
|
|
||||||
BlockOrExpr::new_expr(expr)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a decoder for a single enum variant/struct:
|
|
||||||
/// - `outer_pat_path` is the path to this enum variant/struct
|
|
||||||
/// - `getarg` should retrieve the `usize`-th field with name `@str`.
|
|
||||||
fn decode_static_fields<F>(
|
|
||||||
cx: &ExtCtxt<'_>,
|
|
||||||
trait_span: Span,
|
|
||||||
outer_pat_path: ast::Path,
|
|
||||||
fields: &StaticFields,
|
|
||||||
mut getarg: F,
|
|
||||||
) -> P<Expr>
|
|
||||||
where
|
|
||||||
F: FnMut(&ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
|
|
||||||
{
|
|
||||||
match fields {
|
|
||||||
Unnamed(fields, is_tuple) => {
|
|
||||||
let path_expr = cx.expr_path(outer_pat_path);
|
|
||||||
if matches!(is_tuple, IsTuple::No) {
|
|
||||||
path_expr
|
|
||||||
} else {
|
|
||||||
let fields = fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, &span)| getarg(cx, span, Symbol::intern(&format!("_field{i}")), i))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
cx.expr_call(trait_span, path_expr, fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Named(fields) => {
|
|
||||||
// use the field's span to get nicer error messages.
|
|
||||||
let fields = fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, &(ident, span, _))| {
|
|
||||||
let arg = getarg(cx, span, ident.name, i);
|
|
||||||
cx.field_imm(span, ident, arg)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
cx.expr_struct(trait_span, outer_pat_path, fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_default(
|
||||||
StaticStruct(_, fields) => {
|
StaticStruct(_, fields) => {
|
||||||
default_struct_substructure(cx, trait_span, substr, fields)
|
default_struct_substructure(cx, trait_span, substr, fields)
|
||||||
}
|
}
|
||||||
StaticEnum(enum_def, _) => {
|
StaticEnum(enum_def) => {
|
||||||
default_enum_substructure(cx, trait_span, enum_def, item.span())
|
default_enum_substructure(cx, trait_span, enum_def, item.span())
|
||||||
}
|
}
|
||||||
_ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"),
|
_ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"),
|
||||||
|
|
|
@ -1,284 +0,0 @@
|
||||||
//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
|
|
||||||
//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
|
|
||||||
//! type-defining items may be tagged with
|
|
||||||
//! `#[derive(RustcEncodable, RustcDecodable)]`.
|
|
||||||
//!
|
|
||||||
//! For example, a type like:
|
|
||||||
//!
|
|
||||||
//! ```ignore (old code)
|
|
||||||
//! #[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
//! struct Node { id: usize }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! would generate two implementations like:
|
|
||||||
//!
|
|
||||||
//! ```ignore (old code)
|
|
||||||
//! # struct Node { id: usize }
|
|
||||||
//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
|
|
||||||
//! fn encode(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
//! s.emit_struct("Node", 1, |this| {
|
|
||||||
//! this.emit_struct_field("id", 0, |this| {
|
|
||||||
//! Encodable::encode(&self.id, this)
|
|
||||||
//! /* this.emit_usize(self.id) can also be used */
|
|
||||||
//! })
|
|
||||||
//! })
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
|
|
||||||
//! fn decode(d: &mut D) -> Result<Node, E> {
|
|
||||||
//! d.read_struct("Node", 1, |this| {
|
|
||||||
//! match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
|
|
||||||
//! Ok(id) => Ok(Node { id: id }),
|
|
||||||
//! Err(e) => Err(e),
|
|
||||||
//! }
|
|
||||||
//! })
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Other interesting scenarios are when the item has type parameters or
|
|
||||||
//! references other non-built-in types. A type definition like:
|
|
||||||
//!
|
|
||||||
//! ```ignore (old code)
|
|
||||||
//! # #[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
//! # struct Span;
|
|
||||||
//! #[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
//! struct Spanned<T> { node: T, span: Span }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! would yield functions like:
|
|
||||||
//!
|
|
||||||
//! ```ignore (old code)
|
|
||||||
//! # #[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
//! # struct Span;
|
|
||||||
//! # struct Spanned<T> { node: T, span: Span }
|
|
||||||
//! impl<
|
|
||||||
//! S: Encoder<E>,
|
|
||||||
//! E,
|
|
||||||
//! T: Encodable<S, E>
|
|
||||||
//! > Encodable<S, E> for Spanned<T> {
|
|
||||||
//! fn encode(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
//! s.emit_struct("Spanned", 2, |this| {
|
|
||||||
//! this.emit_struct_field("node", 0, |this| self.node.encode(this))
|
|
||||||
//! .unwrap();
|
|
||||||
//! this.emit_struct_field("span", 1, |this| self.span.encode(this))
|
|
||||||
//! })
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl<
|
|
||||||
//! D: Decoder<E>,
|
|
||||||
//! E,
|
|
||||||
//! T: Decodable<D, E>
|
|
||||||
//! > Decodable<D, E> for Spanned<T> {
|
|
||||||
//! fn decode(d: &mut D) -> Result<Spanned<T>, E> {
|
|
||||||
//! d.read_struct("Spanned", 2, |this| {
|
|
||||||
//! Ok(Spanned {
|
|
||||||
//! node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
|
|
||||||
//! .unwrap(),
|
|
||||||
//! span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
|
|
||||||
//! .unwrap(),
|
|
||||||
//! })
|
|
||||||
//! })
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
|
|
||||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
|
||||||
use rustc_span::{Ident, Span, Symbol, sym};
|
|
||||||
use thin_vec::{ThinVec, thin_vec};
|
|
||||||
|
|
||||||
use crate::deriving::generic::ty::*;
|
|
||||||
use crate::deriving::generic::*;
|
|
||||||
use crate::deriving::pathvec_std;
|
|
||||||
|
|
||||||
pub(crate) fn expand_deriving_rustc_encodable(
|
|
||||||
cx: &ExtCtxt<'_>,
|
|
||||||
span: Span,
|
|
||||||
mitem: &MetaItem,
|
|
||||||
item: &Annotatable,
|
|
||||||
push: &mut dyn FnMut(Annotatable),
|
|
||||||
is_const: bool,
|
|
||||||
) {
|
|
||||||
let krate = sym::rustc_serialize;
|
|
||||||
let typaram = sym::__S;
|
|
||||||
|
|
||||||
let trait_def = TraitDef {
|
|
||||||
span,
|
|
||||||
path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
|
|
||||||
skip_path_as_bound: false,
|
|
||||||
needs_copy_as_bound_if_packed: true,
|
|
||||||
additional_bounds: Vec::new(),
|
|
||||||
supports_unions: false,
|
|
||||||
methods: vec![MethodDef {
|
|
||||||
name: sym::encode,
|
|
||||||
generics: Bounds {
|
|
||||||
bounds: vec![(typaram, vec![Path::new_(
|
|
||||||
vec![krate, sym::Encoder],
|
|
||||||
vec![],
|
|
||||||
PathKind::Global,
|
|
||||||
)])],
|
|
||||||
},
|
|
||||||
explicit_self: true,
|
|
||||||
nonself_args: vec![(
|
|
||||||
Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
|
|
||||||
sym::s,
|
|
||||||
)],
|
|
||||||
ret_ty: Path(Path::new_(
|
|
||||||
pathvec_std!(result::Result),
|
|
||||||
vec![
|
|
||||||
Box::new(Unit),
|
|
||||||
Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))),
|
|
||||||
],
|
|
||||||
PathKind::Std,
|
|
||||||
)),
|
|
||||||
attributes: AttrVec::new(),
|
|
||||||
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
|
|
||||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
|
||||||
encodable_substructure(a, b, c, krate)
|
|
||||||
})),
|
|
||||||
}],
|
|
||||||
associated_types: Vec::new(),
|
|
||||||
is_const,
|
|
||||||
};
|
|
||||||
|
|
||||||
trait_def.expand(cx, mitem, item, push)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encodable_substructure(
|
|
||||||
cx: &ExtCtxt<'_>,
|
|
||||||
trait_span: Span,
|
|
||||||
substr: &Substructure<'_>,
|
|
||||||
krate: Symbol,
|
|
||||||
) -> BlockOrExpr {
|
|
||||||
let encoder = substr.nonselflike_args[0].clone();
|
|
||||||
// throw an underscore in front to suppress unused variable warnings
|
|
||||||
let blkarg = Ident::new(sym::_e, trait_span);
|
|
||||||
let blkencoder = cx.expr_ident(trait_span, blkarg);
|
|
||||||
let fn_path = cx.expr_path(cx.path_global(trait_span, vec![
|
|
||||||
Ident::new(krate, trait_span),
|
|
||||||
Ident::new(sym::Encodable, trait_span),
|
|
||||||
Ident::new(sym::encode, trait_span),
|
|
||||||
]));
|
|
||||||
|
|
||||||
match substr.fields {
|
|
||||||
Struct(_, fields) => {
|
|
||||||
let fn_emit_struct_field_path =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
|
||||||
let mut stmts = ThinVec::new();
|
|
||||||
for (i, &FieldInfo { name, ref self_expr, span, .. }) in fields.iter().enumerate() {
|
|
||||||
let name = match name {
|
|
||||||
Some(id) => id.name,
|
|
||||||
None => Symbol::intern(&format!("_field{i}")),
|
|
||||||
};
|
|
||||||
let self_ref = cx.expr_addr_of(span, self_expr.clone());
|
|
||||||
let enc =
|
|
||||||
cx.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
|
|
||||||
let lambda = cx.lambda1(span, enc, blkarg);
|
|
||||||
let call = cx.expr_call_global(span, fn_emit_struct_field_path.clone(), thin_vec![
|
|
||||||
blkencoder.clone(),
|
|
||||||
cx.expr_str(span, name),
|
|
||||||
cx.expr_usize(span, i),
|
|
||||||
lambda,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// last call doesn't need a try!
|
|
||||||
let last = fields.len() - 1;
|
|
||||||
let call = if i != last {
|
|
||||||
cx.expr_try(span, call)
|
|
||||||
} else {
|
|
||||||
cx.expr(span, ExprKind::Ret(Some(call)))
|
|
||||||
};
|
|
||||||
|
|
||||||
let stmt = cx.stmt_expr(call);
|
|
||||||
stmts.push(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unit structs have no fields and need to return Ok()
|
|
||||||
let blk = if stmts.is_empty() {
|
|
||||||
let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
|
|
||||||
cx.lambda1(trait_span, ok, blkarg)
|
|
||||||
} else {
|
|
||||||
cx.lambda_stmts_1(trait_span, stmts, blkarg)
|
|
||||||
};
|
|
||||||
|
|
||||||
let fn_emit_struct_path =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct]);
|
|
||||||
|
|
||||||
let expr = cx.expr_call_global(trait_span, fn_emit_struct_path, thin_vec![
|
|
||||||
encoder,
|
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
|
||||||
cx.expr_usize(trait_span, fields.len()),
|
|
||||||
blk,
|
|
||||||
]);
|
|
||||||
BlockOrExpr::new_expr(expr)
|
|
||||||
}
|
|
||||||
|
|
||||||
EnumMatching(idx, variant, fields) => {
|
|
||||||
// We're not generating an AST that the borrow checker is expecting,
|
|
||||||
// so we need to generate a unique local variable to take the
|
|
||||||
// mutable loan out on, otherwise we get conflicts which don't
|
|
||||||
// actually exist.
|
|
||||||
let me = cx.stmt_let(trait_span, false, blkarg, encoder);
|
|
||||||
let encoder = cx.expr_ident(trait_span, blkarg);
|
|
||||||
|
|
||||||
let fn_emit_enum_variant_arg_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant_arg]);
|
|
||||||
|
|
||||||
let mut stmts = ThinVec::new();
|
|
||||||
if !fields.is_empty() {
|
|
||||||
let last = fields.len() - 1;
|
|
||||||
for (i, &FieldInfo { ref self_expr, span, .. }) in fields.iter().enumerate() {
|
|
||||||
let self_ref = cx.expr_addr_of(span, self_expr.clone());
|
|
||||||
let enc = cx
|
|
||||||
.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
|
|
||||||
let lambda = cx.lambda1(span, enc, blkarg);
|
|
||||||
|
|
||||||
let call = cx.expr_call_global(
|
|
||||||
span,
|
|
||||||
fn_emit_enum_variant_arg_path.clone(),
|
|
||||||
thin_vec![blkencoder.clone(), cx.expr_usize(span, i), lambda],
|
|
||||||
);
|
|
||||||
let call = if i != last {
|
|
||||||
cx.expr_try(span, call)
|
|
||||||
} else {
|
|
||||||
cx.expr(span, ExprKind::Ret(Some(call)))
|
|
||||||
};
|
|
||||||
stmts.push(cx.stmt_expr(call));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
|
|
||||||
let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
|
|
||||||
stmts.push(cx.stmt_expr(ret_ok));
|
|
||||||
}
|
|
||||||
|
|
||||||
let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
|
|
||||||
let name = cx.expr_str(trait_span, variant.ident.name);
|
|
||||||
|
|
||||||
let fn_emit_enum_variant_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant]);
|
|
||||||
|
|
||||||
let call = cx.expr_call_global(trait_span, fn_emit_enum_variant_path, thin_vec![
|
|
||||||
blkencoder,
|
|
||||||
name,
|
|
||||||
cx.expr_usize(trait_span, *idx),
|
|
||||||
cx.expr_usize(trait_span, fields.len()),
|
|
||||||
blk,
|
|
||||||
]);
|
|
||||||
|
|
||||||
let blk = cx.lambda1(trait_span, call, blkarg);
|
|
||||||
let fn_emit_enum_path: Vec<_> =
|
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum]);
|
|
||||||
let expr = cx.expr_call_global(trait_span, fn_emit_enum_path, thin_vec![
|
|
||||||
encoder,
|
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
|
||||||
blk
|
|
||||||
]);
|
|
||||||
BlockOrExpr::new_mixed(thin_vec![me], Some(expr))
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => cx.dcx().bug("expected Struct or EnumMatching in derive(Encodable)"),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -311,7 +311,7 @@ pub(crate) enum SubstructureFields<'a> {
|
||||||
/// Matching variants of the enum: variant index, ast::Variant,
|
/// Matching variants of the enum: variant index, ast::Variant,
|
||||||
/// fields: the field name is only non-`None` in the case of a struct
|
/// fields: the field name is only non-`None` in the case of a struct
|
||||||
/// variant.
|
/// variant.
|
||||||
EnumMatching(usize, &'a ast::Variant, Vec<FieldInfo>),
|
EnumMatching(&'a ast::Variant, Vec<FieldInfo>),
|
||||||
|
|
||||||
/// The discriminant of an enum. The first field is a `FieldInfo` for the discriminants, as
|
/// The discriminant of an enum. The first field is a `FieldInfo` for the discriminants, as
|
||||||
/// if they were fields. The second field is the expression to combine the
|
/// if they were fields. The second field is the expression to combine the
|
||||||
|
@ -322,7 +322,7 @@ pub(crate) enum SubstructureFields<'a> {
|
||||||
StaticStruct(&'a ast::VariantData, StaticFields),
|
StaticStruct(&'a ast::VariantData, StaticFields),
|
||||||
|
|
||||||
/// A static method where `Self` is an enum.
|
/// A static method where `Self` is an enum.
|
||||||
StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
|
StaticEnum(&'a ast::EnumDef),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Combine the values of all the fields together. The last argument is
|
/// Combine the values of all the fields together. The last argument is
|
||||||
|
@ -1270,7 +1270,7 @@ impl<'a> MethodDef<'a> {
|
||||||
trait_,
|
trait_,
|
||||||
type_ident,
|
type_ident,
|
||||||
nonselflike_args,
|
nonselflike_args,
|
||||||
&EnumMatching(0, variant, Vec::new()),
|
&EnumMatching(variant, Vec::new()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1282,9 +1282,8 @@ impl<'a> MethodDef<'a> {
|
||||||
// where each tuple has length = selflike_args.len()
|
// where each tuple has length = selflike_args.len()
|
||||||
let mut match_arms: ThinVec<ast::Arm> = variants
|
let mut match_arms: ThinVec<ast::Arm> = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.filter(|&v| !(unify_fieldless_variants && v.data.fields().is_empty()))
|
||||||
.filter(|&(_, v)| !(unify_fieldless_variants && v.data.fields().is_empty()))
|
.map(|variant| {
|
||||||
.map(|(index, variant)| {
|
|
||||||
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
|
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
|
||||||
// (see "Final wrinkle" note below for why.)
|
// (see "Final wrinkle" note below for why.)
|
||||||
|
|
||||||
|
@ -1316,7 +1315,7 @@ impl<'a> MethodDef<'a> {
|
||||||
// expressions for referencing every field of every
|
// expressions for referencing every field of every
|
||||||
// Self arg, assuming all are instances of VariantK.
|
// Self arg, assuming all are instances of VariantK.
|
||||||
// Build up code associated with such a case.
|
// Build up code associated with such a case.
|
||||||
let substructure = EnumMatching(index, variant, fields);
|
let substructure = EnumMatching(variant, fields);
|
||||||
let arm_expr = self
|
let arm_expr = self
|
||||||
.call_substructure_method(
|
.call_substructure_method(
|
||||||
cx,
|
cx,
|
||||||
|
@ -1344,7 +1343,7 @@ impl<'a> MethodDef<'a> {
|
||||||
trait_,
|
trait_,
|
||||||
type_ident,
|
type_ident,
|
||||||
nonselflike_args,
|
nonselflike_args,
|
||||||
&EnumMatching(0, v, Vec::new()),
|
&EnumMatching(v, Vec::new()),
|
||||||
)
|
)
|
||||||
.into_expr(cx, span),
|
.into_expr(cx, span),
|
||||||
)
|
)
|
||||||
|
@ -1407,21 +1406,12 @@ impl<'a> MethodDef<'a> {
|
||||||
type_ident: Ident,
|
type_ident: Ident,
|
||||||
nonselflike_args: &[P<Expr>],
|
nonselflike_args: &[P<Expr>],
|
||||||
) -> BlockOrExpr {
|
) -> BlockOrExpr {
|
||||||
let summary = enum_def
|
|
||||||
.variants
|
|
||||||
.iter()
|
|
||||||
.map(|v| {
|
|
||||||
let sp = v.span.with_ctxt(trait_.span.ctxt());
|
|
||||||
let summary = trait_.summarise_struct(cx, &v.data);
|
|
||||||
(v.ident, sp, summary)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
self.call_substructure_method(
|
self.call_substructure_method(
|
||||||
cx,
|
cx,
|
||||||
trait_,
|
trait_,
|
||||||
type_ident,
|
type_ident,
|
||||||
nonselflike_args,
|
nonselflike_args,
|
||||||
&StaticEnum(enum_def, summary),
|
&StaticEnum(enum_def),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ pub(crate) struct Path {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) enum PathKind {
|
pub(crate) enum PathKind {
|
||||||
Local,
|
Local,
|
||||||
Global,
|
|
||||||
Std,
|
Std,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +56,6 @@ impl Path {
|
||||||
let params = tys.map(GenericArg::Type).collect();
|
let params = tys.map(GenericArg::Type).collect();
|
||||||
|
|
||||||
match self.kind {
|
match self.kind {
|
||||||
PathKind::Global => cx.path_all(span, true, idents, params),
|
|
||||||
PathKind::Local => cx.path_all(span, false, idents, params),
|
PathKind::Local => cx.path_all(span, false, idents, params),
|
||||||
PathKind::Std => {
|
PathKind::Std => {
|
||||||
let def_site = cx.with_def_site_ctxt(DUMMY_SP);
|
let def_site = cx.with_def_site_ctxt(DUMMY_SP);
|
||||||
|
|
|
@ -23,9 +23,7 @@ pub(crate) mod bounds;
|
||||||
pub(crate) mod clone;
|
pub(crate) mod clone;
|
||||||
pub(crate) mod coerce_pointee;
|
pub(crate) mod coerce_pointee;
|
||||||
pub(crate) mod debug;
|
pub(crate) mod debug;
|
||||||
pub(crate) mod decodable;
|
|
||||||
pub(crate) mod default;
|
pub(crate) mod default;
|
||||||
pub(crate) mod encodable;
|
|
||||||
pub(crate) mod hash;
|
pub(crate) mod hash;
|
||||||
|
|
||||||
#[path = "cmp/eq.rs"]
|
#[path = "cmp/eq.rs"]
|
||||||
|
|
|
@ -132,8 +132,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
||||||
Ord: ord::expand_deriving_ord,
|
Ord: ord::expand_deriving_ord,
|
||||||
PartialEq: partial_eq::expand_deriving_partial_eq,
|
PartialEq: partial_eq::expand_deriving_partial_eq,
|
||||||
PartialOrd: partial_ord::expand_deriving_partial_ord,
|
PartialOrd: partial_ord::expand_deriving_partial_ord,
|
||||||
RustcDecodable: decodable::expand_deriving_rustc_decodable,
|
|
||||||
RustcEncodable: encodable::expand_deriving_rustc_encodable,
|
|
||||||
CoercePointee: coerce_pointee::expand_deriving_coerce_pointee,
|
CoercePointee: coerce_pointee::expand_deriving_coerce_pointee,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -644,7 +644,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
found_label: &dyn fmt::Display,
|
found_label: &dyn fmt::Display,
|
||||||
found: DiagStyledString,
|
found: DiagStyledString,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"")
|
self.note_expected_found_extra(
|
||||||
|
expected_label,
|
||||||
|
expected,
|
||||||
|
found_label,
|
||||||
|
found,
|
||||||
|
DiagStyledString::normal(""),
|
||||||
|
DiagStyledString::normal(""),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
|
@ -654,8 +661,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
expected: DiagStyledString,
|
expected: DiagStyledString,
|
||||||
found_label: &dyn fmt::Display,
|
found_label: &dyn fmt::Display,
|
||||||
found: DiagStyledString,
|
found: DiagStyledString,
|
||||||
expected_extra: &dyn fmt::Display,
|
expected_extra: DiagStyledString,
|
||||||
found_extra: &dyn fmt::Display,
|
found_extra: DiagStyledString,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let expected_label = expected_label.to_string();
|
let expected_label = expected_label.to_string();
|
||||||
let expected_label = if expected_label.is_empty() {
|
let expected_label = if expected_label.is_empty() {
|
||||||
|
@ -680,10 +687,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
expected_label
|
expected_label
|
||||||
))];
|
))];
|
||||||
msg.extend(expected.0);
|
msg.extend(expected.0);
|
||||||
msg.push(StringPart::normal(format!("`{expected_extra}\n")));
|
msg.push(StringPart::normal(format!("`")));
|
||||||
|
msg.extend(expected_extra.0);
|
||||||
|
msg.push(StringPart::normal(format!("\n")));
|
||||||
msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
|
msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
|
||||||
msg.extend(found.0);
|
msg.extend(found.0);
|
||||||
msg.push(StringPart::normal(format!("`{found_extra}")));
|
msg.push(StringPart::normal(format!("`")));
|
||||||
|
msg.extend(found_extra.0);
|
||||||
|
|
||||||
// For now, just attach these as notes.
|
// For now, just attach these as notes.
|
||||||
self.highlighted_note(msg);
|
self.highlighted_note(msg);
|
||||||
|
|
|
@ -616,7 +616,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
|
EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
|
||||||
),
|
),
|
||||||
rustc_attr!(
|
rustc_attr!(
|
||||||
rustc_allowed_through_unstable_modules, Normal, template!(Word, NameValueStr: "deprecation message"),
|
rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"),
|
||||||
WarnFollowing, EncodeCrossCrate::No,
|
WarnFollowing, EncodeCrossCrate::No,
|
||||||
"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
|
"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
|
||||||
through unstable paths"
|
through unstable paths"
|
||||||
|
|
|
@ -50,7 +50,6 @@ use rustc_infer::traits::{
|
||||||
IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation,
|
IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation,
|
||||||
PredicateObligations,
|
PredicateObligations,
|
||||||
};
|
};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::traits::BuiltinImplSource;
|
use rustc_middle::traits::BuiltinImplSource;
|
||||||
use rustc_middle::ty::adjustment::{
|
use rustc_middle::ty::adjustment::{
|
||||||
|
@ -1937,7 +1936,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
cond_expr.span.desugaring_kind(),
|
cond_expr.span.desugaring_kind(),
|
||||||
None | Some(DesugaringKind::WhileLoop)
|
None | Some(DesugaringKind::WhileLoop)
|
||||||
)
|
)
|
||||||
&& !in_external_macro(fcx.tcx.sess, cond_expr.span)
|
&& !cond_expr.span.in_external_macro(fcx.tcx.sess.source_map())
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
cond_expr.kind,
|
cond_expr.kind,
|
||||||
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
|
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
|
||||||
|
|
|
@ -14,7 +14,6 @@ use rustc_hir::{
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_hir_analysis::suggest_impl_trait;
|
use rustc_hir_analysis::suggest_impl_trait;
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::middle::stability::EvalResult;
|
use rustc_middle::middle::stability::EvalResult;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
|
@ -770,7 +769,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// If the expression is from an external macro, then do not suggest
|
// If the expression is from an external macro, then do not suggest
|
||||||
// adding a semicolon, because there's nowhere to put it.
|
// adding a semicolon, because there's nowhere to put it.
|
||||||
// See issue #81943.
|
// See issue #81943.
|
||||||
&& !in_external_macro(self.tcx.sess, expression.span) =>
|
&& !expression.span.in_external_macro(self.tcx.sess.source_map()) =>
|
||||||
{
|
{
|
||||||
if needs_block {
|
if needs_block {
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
|
@ -2261,7 +2260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
expr_ty: Ty<'tcx>,
|
expr_ty: Ty<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if in_external_macro(self.tcx.sess, expr.span) {
|
if expr.span.in_external_macro(self.tcx.sess.source_map()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let ty::Adt(expected_adt, args) = expected.kind() {
|
if let ty::Adt(expected_adt, args) = expected.kind() {
|
||||||
|
@ -2589,14 +2588,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
)> {
|
)> {
|
||||||
let sess = self.sess();
|
let sess = self.sess();
|
||||||
let sp = expr.span;
|
let sp = expr.span;
|
||||||
|
let sm = sess.source_map();
|
||||||
|
|
||||||
// If the span is from an external macro, there's no suggestion we can make.
|
// If the span is from an external macro, there's no suggestion we can make.
|
||||||
if in_external_macro(sess, sp) {
|
if sp.in_external_macro(sm) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sm = sess.source_map();
|
|
||||||
|
|
||||||
let replace_prefix = |s: &str, old: &str, new: &str| {
|
let replace_prefix = |s: &str, old: &str, new: &str| {
|
||||||
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
|
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::FnKind as HirFnKind;
|
use rustc_hir::intravisit::FnKind as HirFnKind;
|
||||||
use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
|
use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
|
||||||
|
@ -2029,7 +2028,7 @@ impl ExplicitOutlivesRequirements {
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = bound.span().find_ancestor_inside(predicate_span)?;
|
let span = bound.span().find_ancestor_inside(predicate_span)?;
|
||||||
if in_external_macro(tcx.sess, span) {
|
if span.in_external_macro(tcx.sess.source_map()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ pub(super) fn unexpected_cfg_name(
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
|
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
|
||||||
let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
|
let is_from_external_macro = name_span.in_external_macro(sess.source_map());
|
||||||
let mut is_feature_cfg = name == sym::feature;
|
let mut is_feature_cfg = name == sym::feature;
|
||||||
|
|
||||||
let code_sugg = if is_feature_cfg && is_from_cargo {
|
let code_sugg = if is_feature_cfg && is_from_cargo {
|
||||||
|
@ -281,7 +281,7 @@ pub(super) fn unexpected_cfg_value(
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
|
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
|
||||||
let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
|
let is_from_external_macro = name_span.in_external_macro(sess.source_map());
|
||||||
|
|
||||||
// Show the full list if all possible values for a given name, but don't do it
|
// Show the full list if all possible values for a given name, but don't do it
|
||||||
// for names as the possibilities could be very long
|
// for names as the possibilities could be very long
|
||||||
|
|
|
@ -2,7 +2,6 @@ use rustc_ast as ast;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{self as hir, LangItem};
|
use rustc_hir::{self as hir, LangItem};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::{bug, ty};
|
use rustc_middle::{bug, ty};
|
||||||
use rustc_parse_format::{ParseMode, Parser, Piece};
|
use rustc_parse_format::{ParseMode, Parser, Piece};
|
||||||
use rustc_session::lint::FutureIncompatibilityReason;
|
use rustc_session::lint::FutureIncompatibilityReason;
|
||||||
|
@ -100,7 +99,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
||||||
|
|
||||||
let (span, panic, symbol) = panic_call(cx, f);
|
let (span, panic, symbol) = panic_call(cx, f);
|
||||||
|
|
||||||
if in_external_macro(cx.sess(), span) {
|
if span.in_external_macro(cx.sess().source_map()) {
|
||||||
// Nothing that can be done about it in the current crate.
|
// Nothing that can be done about it in the current crate.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -229,14 +228,15 @@ fn check_panic_str<'tcx>(
|
||||||
|
|
||||||
let (span, _, _) = panic_call(cx, f);
|
let (span, _, _) = panic_call(cx, f);
|
||||||
|
|
||||||
if in_external_macro(cx.sess(), span) && in_external_macro(cx.sess(), arg.span) {
|
let sm = cx.sess().source_map();
|
||||||
|
if span.in_external_macro(sm) && arg.span.in_external_macro(sm) {
|
||||||
// Nothing that can be done about it in the current crate.
|
// Nothing that can be done about it in the current crate.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fmt_span = arg.span.source_callsite();
|
let fmt_span = arg.span.source_callsite();
|
||||||
|
|
||||||
let (snippet, style) = match cx.sess().psess.source_map().span_to_snippet(fmt_span) {
|
let (snippet, style) = match sm.span_to_snippet(fmt_span) {
|
||||||
Ok(snippet) => {
|
Ok(snippet) => {
|
||||||
// Count the number of `#`s between the `r` and `"`.
|
// Count the number of `#`s between the `r` and `"`.
|
||||||
let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
|
let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
|
||||||
|
@ -283,7 +283,7 @@ fn check_panic_str<'tcx>(
|
||||||
/// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
|
/// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
|
||||||
/// and the type of (opening) delimiter used.
|
/// and the type of (opening) delimiter used.
|
||||||
fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char)> {
|
fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char)> {
|
||||||
let snippet = cx.sess().psess.source_map().span_to_snippet(span).ok()?;
|
let snippet = cx.sess().source_map().span_to_snippet(span).ok()?;
|
||||||
let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?;
|
let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?;
|
||||||
let close = snippet.rfind(|c| ")]}".contains(c))?;
|
let close = snippet.rfind(|c| ")]}".contains(c))?;
|
||||||
Some((
|
Some((
|
||||||
|
|
|
@ -8,8 +8,7 @@ use rustc_macros::{Decodable, Encodable, HashStable};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
|
use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
|
||||||
use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
|
use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
|
||||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
use rustc_span::{DUMMY_SP, Span, Symbol, kw};
|
||||||
use rustc_span::{DUMMY_SP, DesugaringKind, Span, Symbol, kw};
|
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
|
@ -201,7 +200,7 @@ impl LintExpectation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn explain_lint_level_source(
|
fn explain_lint_level_source(
|
||||||
lint: &'static Lint,
|
lint: &'static Lint,
|
||||||
level: Level,
|
level: Level,
|
||||||
src: LintLevelSource,
|
src: LintLevelSource,
|
||||||
|
@ -325,7 +324,7 @@ pub fn lint_level(
|
||||||
// If this code originates in a foreign macro, aka something that this crate
|
// If this code originates in a foreign macro, aka something that this crate
|
||||||
// did not itself author, then it's likely that there's nothing this crate
|
// did not itself author, then it's likely that there's nothing this crate
|
||||||
// can do about it. We probably want to skip the lint entirely.
|
// can do about it. We probably want to skip the lint entirely.
|
||||||
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
|
if err.span.primary_spans().iter().any(|s| s.in_external_macro(sess.source_map())) {
|
||||||
// Any suggestions made here are likely to be incorrect, so anything we
|
// Any suggestions made here are likely to be incorrect, so anything we
|
||||||
// emit shouldn't be automatically fixed by rustfix.
|
// emit shouldn't be automatically fixed by rustfix.
|
||||||
err.disable_suggestions();
|
err.disable_suggestions();
|
||||||
|
@ -422,36 +421,3 @@ pub fn lint_level(
|
||||||
}
|
}
|
||||||
lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
|
lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether `span` originates in a foreign crate's external macro.
|
|
||||||
///
|
|
||||||
/// This is used to test whether a lint should not even begin to figure out whether it should
|
|
||||||
/// be reported on the current node.
|
|
||||||
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
|
|
||||||
let expn_data = span.ctxt().outer_expn_data();
|
|
||||||
match expn_data.kind {
|
|
||||||
ExpnKind::Root
|
|
||||||
| ExpnKind::Desugaring(
|
|
||||||
DesugaringKind::ForLoop
|
|
||||||
| DesugaringKind::WhileLoop
|
|
||||||
| DesugaringKind::OpaqueTy
|
|
||||||
| DesugaringKind::Async
|
|
||||||
| DesugaringKind::Await,
|
|
||||||
) => false,
|
|
||||||
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
|
|
||||||
ExpnKind::Macro(MacroKind::Bang, _) => {
|
|
||||||
// Dummy span for the `def_site` means it's an external macro.
|
|
||||||
expn_data.def_site.is_dummy() || sess.source_map().is_imported(expn_data.def_site)
|
|
||||||
}
|
|
||||||
ExpnKind::Macro { .. } => true, // definitely a plugin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return whether `span` is generated by `async` or `await`.
|
|
||||||
pub fn is_from_async_await(span: Span) -> bool {
|
|
||||||
let expn_data = span.ctxt().outer_expn_data();
|
|
||||||
match expn_data.kind {
|
|
||||||
ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -92,51 +92,88 @@ impl<'tcx> MonoItem<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
|
pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
|
||||||
let generate_cgu_internal_copies =
|
// The case handling here is written in the same style as cross_crate_inlinable, we first
|
||||||
(tcx.sess.opts.optimize != OptLevel::No) && !tcx.sess.link_dead_code();
|
// handle the cases where we must use a particular instantiation mode, then cascade down
|
||||||
|
// through a sequence of heuristics.
|
||||||
|
|
||||||
match *self {
|
// The first thing we do is detect MonoItems which we must instantiate exactly once in the
|
||||||
MonoItem::Fn(ref instance) => {
|
// whole program.
|
||||||
let entry_def_id = tcx.entry_fn(()).map(|(id, _)| id);
|
|
||||||
// If this function isn't inlined or otherwise has an extern
|
// Statics and global_asm! must be instantiated exactly once.
|
||||||
// indicator, then we'll be creating a globally shared version.
|
let instance = match *self {
|
||||||
|
MonoItem::Fn(instance) => instance,
|
||||||
|
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
|
||||||
|
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Similarly, the executable entrypoint must be instantiated exactly once.
|
||||||
|
if let Some((entry_def_id, _)) = tcx.entry_fn(()) {
|
||||||
|
if instance.def_id() == entry_def_id {
|
||||||
|
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the function is #[naked] or contains any other attribute that requires exactly-once
|
||||||
|
// instantiation:
|
||||||
let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
|
let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
|
||||||
if codegen_fn_attrs.contains_extern_indicator()
|
if codegen_fn_attrs.contains_extern_indicator()
|
||||||
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
|
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
|
||||||
|| !instance.def.generates_cgu_internal_copy(tcx)
|
|
||||||
|| Some(instance.def_id()) == entry_def_id
|
|
||||||
{
|
{
|
||||||
return InstantiationMode::GloballyShared { may_conflict: false };
|
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
|
// FIXME: The logic for which functions are permitted to get LocalCopy is actually spread
|
||||||
&& self.is_generic_fn()
|
// across 4 functions:
|
||||||
{
|
// * cross_crate_inlinable(def_id)
|
||||||
// Upgrade inline(never) to a globally shared instance.
|
// * InstanceKind::requires_inline
|
||||||
|
// * InstanceKind::generate_cgu_internal_copy
|
||||||
|
// * MonoItem::instantiation_mode
|
||||||
|
// Since reachable_non_generics calls InstanceKind::generates_cgu_internal_copy to decide
|
||||||
|
// which symbols this crate exports, we are obligated to only generate LocalCopy when
|
||||||
|
// generates_cgu_internal_copy returns true.
|
||||||
|
if !instance.def.generates_cgu_internal_copy(tcx) {
|
||||||
|
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beginning of heuristics. The handling of link-dead-code and inline(always) are QoL only,
|
||||||
|
// the compiler should not crash and linkage should work, but codegen may be undesirable.
|
||||||
|
|
||||||
|
// -Clink-dead-code was given an unfortunate name; the point of the flag is to assist
|
||||||
|
// coverage tools which rely on having every function in the program appear in the
|
||||||
|
// generated code. If we select LocalCopy, functions which are not used because they are
|
||||||
|
// missing test coverage will disappear from such coverage reports, defeating the point.
|
||||||
|
// Note that -Cinstrument-coverage does not require such assistance from us, only coverage
|
||||||
|
// tools implemented without compiler support ironically require a special compiler flag.
|
||||||
|
if tcx.sess.link_dead_code() {
|
||||||
return InstantiationMode::GloballyShared { may_conflict: true };
|
return InstantiationMode::GloballyShared { may_conflict: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point we don't have explicit linkage and we're an
|
// To ensure that #[inline(always)] can be inlined as much as possible, especially in unoptimized
|
||||||
// inlined function. If this crate's build settings permit,
|
// builds, we always select LocalCopy.
|
||||||
// we'll be creating a local copy per CGU.
|
if codegen_fn_attrs.inline.always() {
|
||||||
if generate_cgu_internal_copies {
|
|
||||||
return InstantiationMode::LocalCopy;
|
return InstantiationMode::LocalCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, if this is `#[inline(always)]` we're sure to respect
|
// #[inline(never)] functions in general are poor candidates for inlining and thus since
|
||||||
// that with an inline copy per CGU, but otherwise we'll be
|
// LocalCopy generally increases code size for the benefit of optimizations from inlining,
|
||||||
// creating one copy of this `#[inline]` function which may
|
// we want to give them GloballyShared codegen.
|
||||||
// conflict with upstream crates as it could be an exported
|
// The slight problem is that generic functions need to always support cross-crate
|
||||||
// symbol.
|
// compilation, so all previous stages of the compiler are obligated to treat generic
|
||||||
if tcx.codegen_fn_attrs(instance.def_id()).inline.always() {
|
// functions the same as those that unconditionally get LocalCopy codegen. It's only when
|
||||||
InstantiationMode::LocalCopy
|
// we get here that we can at least not codegen a #[inline(never)] generic function in all
|
||||||
} else {
|
// of our CGUs.
|
||||||
InstantiationMode::GloballyShared { may_conflict: true }
|
if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
|
||||||
}
|
&& self.is_generic_fn()
|
||||||
}
|
{
|
||||||
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
|
return InstantiationMode::GloballyShared { may_conflict: true };
|
||||||
InstantiationMode::GloballyShared { may_conflict: false }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The fallthrough case is to generate LocalCopy for all optimized builds, and
|
||||||
|
// GloballyShared with conflict prevention when optimizations are disabled.
|
||||||
|
match tcx.sess.opts.optimize {
|
||||||
|
OptLevel::No => InstantiationMode::GloballyShared { may_conflict: true },
|
||||||
|
_ => InstantiationMode::LocalCopy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ use std::mem::replace;
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
|
|
||||||
use rustc_attr_parsing::{
|
use rustc_attr_parsing::{
|
||||||
self as attr, AllowedThroughUnstableModules, ConstStability, DeprecatedSince, Stability,
|
self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
|
||||||
StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER,
|
UnstableReason, VERSION_PLACEHOLDER,
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
|
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
|
||||||
|
@ -880,7 +880,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
|
|
||||||
if item_is_allowed {
|
if item_is_allowed {
|
||||||
// The item itself is allowed; check whether the path there is also allowed.
|
// The item itself is allowed; check whether the path there is also allowed.
|
||||||
let is_allowed_through_unstable_modules: Option<AllowedThroughUnstableModules> =
|
let is_allowed_through_unstable_modules: Option<Symbol> =
|
||||||
self.tcx.lookup_stability(def_id).and_then(|stab| match stab.level {
|
self.tcx.lookup_stability(def_id).and_then(|stab| match stab.level {
|
||||||
StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
|
StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
|
||||||
allowed_through_unstable_modules
|
allowed_through_unstable_modules
|
||||||
|
@ -888,9 +888,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
if is_allowed_through_unstable_modules.is_none() {
|
|
||||||
// Check parent modules stability as well if the item the path refers to is itself
|
// Check parent modules stability as well if the item the path refers to is itself
|
||||||
// stable. We only emit warnings for unstable path segments if the item is stable
|
// stable. We only emit errors for unstable path segments if the item is stable
|
||||||
// or allowed because stability is often inherited, so the most common case is that
|
// or allowed because stability is often inherited, so the most common case is that
|
||||||
// both the segments and the item are unstable behind the same feature flag.
|
// both the segments and the item are unstable behind the same feature flag.
|
||||||
//
|
//
|
||||||
|
@ -903,6 +902,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
let parents = path.segments.iter().rev().skip(1);
|
let parents = path.segments.iter().rev().skip(1);
|
||||||
for path_segment in parents {
|
for path_segment in parents {
|
||||||
if let Some(def_id) = path_segment.res.opt_def_id() {
|
if let Some(def_id) = path_segment.res.opt_def_id() {
|
||||||
|
match is_allowed_through_unstable_modules {
|
||||||
|
None => {
|
||||||
|
// Emit a hard stability error if this path is not stable.
|
||||||
|
|
||||||
// use `None` for id to prevent deprecation check
|
// use `None` for id to prevent deprecation check
|
||||||
self.tcx.check_stability_allow_unstable(
|
self.tcx.check_stability_allow_unstable(
|
||||||
def_id,
|
def_id,
|
||||||
|
@ -916,17 +919,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
Some(deprecation) => {
|
||||||
} else if let Some(AllowedThroughUnstableModules::WithDeprecation(deprecation)) =
|
// Call the stability check directly so that we can control which
|
||||||
is_allowed_through_unstable_modules
|
// diagnostic is emitted.
|
||||||
{
|
|
||||||
// Similar to above, but we cannot use `check_stability_allow_unstable` as that would
|
|
||||||
// immediately show the stability error. We just want to know the result and disaplay
|
|
||||||
// our own kind of error.
|
|
||||||
let parents = path.segments.iter().rev().skip(1);
|
|
||||||
for path_segment in parents {
|
|
||||||
if let Some(def_id) = path_segment.res.opt_def_id() {
|
|
||||||
// use `None` for id to prevent deprecation check
|
|
||||||
let eval_result = self.tcx.eval_stability_allow_unstable(
|
let eval_result = self.tcx.eval_stability_allow_unstable(
|
||||||
def_id,
|
def_id,
|
||||||
None,
|
None,
|
||||||
|
@ -971,6 +966,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
intravisit::walk_path(self, path)
|
intravisit::walk_path(self, path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -600,11 +600,43 @@ impl Span {
|
||||||
!self.is_dummy() && sm.is_span_accessible(self)
|
!self.is_dummy() && sm.is_span_accessible(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether `span` originates in a foreign crate's external macro.
|
||||||
|
///
|
||||||
|
/// This is used to test whether a lint should not even begin to figure out whether it should
|
||||||
|
/// be reported on the current node.
|
||||||
|
pub fn in_external_macro(self, sm: &SourceMap) -> bool {
|
||||||
|
let expn_data = self.ctxt().outer_expn_data();
|
||||||
|
match expn_data.kind {
|
||||||
|
ExpnKind::Root
|
||||||
|
| ExpnKind::Desugaring(
|
||||||
|
DesugaringKind::ForLoop
|
||||||
|
| DesugaringKind::WhileLoop
|
||||||
|
| DesugaringKind::OpaqueTy
|
||||||
|
| DesugaringKind::Async
|
||||||
|
| DesugaringKind::Await,
|
||||||
|
) => false,
|
||||||
|
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
|
||||||
|
ExpnKind::Macro(MacroKind::Bang, _) => {
|
||||||
|
// Dummy span for the `def_site` means it's an external macro.
|
||||||
|
expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
|
||||||
|
}
|
||||||
|
ExpnKind::Macro { .. } => true, // definitely a plugin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if `span` originates in a derive-macro's expansion.
|
/// Returns `true` if `span` originates in a derive-macro's expansion.
|
||||||
pub fn in_derive_expansion(self) -> bool {
|
pub fn in_derive_expansion(self) -> bool {
|
||||||
matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
|
matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return whether `span` is generated by `async` or `await`.
|
||||||
|
pub fn is_from_async_await(self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self.ctxt().outer_expn_data().kind,
|
||||||
|
ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Gate suggestions that would not be appropriate in a context the user didn't write.
|
/// Gate suggestions that would not be appropriate in a context the user didn't write.
|
||||||
pub fn can_be_used_for_suggestions(self) -> bool {
|
pub fn can_be_used_for_suggestions(self) -> bool {
|
||||||
!self.from_expansion()
|
!self.from_expansion()
|
||||||
|
|
|
@ -314,8 +314,6 @@ symbols! {
|
||||||
Right,
|
Right,
|
||||||
Rust,
|
Rust,
|
||||||
RustaceansAreAwesome,
|
RustaceansAreAwesome,
|
||||||
RustcDecodable,
|
|
||||||
RustcEncodable,
|
|
||||||
RwLock,
|
RwLock,
|
||||||
RwLockReadGuard,
|
RwLockReadGuard,
|
||||||
RwLockWriteGuard,
|
RwLockWriteGuard,
|
||||||
|
|
|
@ -1722,32 +1722,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeError::Sorts(values) => {
|
TypeError::Sorts(values) => {
|
||||||
let extra = expected == found;
|
let extra = expected == found
|
||||||
|
// Ensure that we don't ever say something like
|
||||||
|
// expected `impl Trait` (opaque type `impl Trait`)
|
||||||
|
// found `impl Trait` (opaque type `impl Trait`)
|
||||||
|
&& values.expected.sort_string(self.tcx)
|
||||||
|
!= values.found.sort_string(self.tcx);
|
||||||
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
|
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
|
||||||
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
|
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
|
||||||
let sm = self.tcx.sess.source_map();
|
let sm = self.tcx.sess.source_map();
|
||||||
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
|
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
|
||||||
format!(
|
DiagStyledString::normal(format!(
|
||||||
" (opaque type at <{}:{}:{}>)",
|
" (opaque type at <{}:{}:{}>)",
|
||||||
sm.filename_for_diagnostics(&pos.file.name),
|
sm.filename_for_diagnostics(&pos.file.name),
|
||||||
pos.line,
|
pos.line,
|
||||||
pos.col.to_usize() + 1,
|
pos.col.to_usize() + 1,
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
(true, ty::Alias(ty::Projection, proj))
|
(true, ty::Alias(ty::Projection, proj))
|
||||||
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
|
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
|
||||||
{
|
{
|
||||||
let sm = self.tcx.sess.source_map();
|
let sm = self.tcx.sess.source_map();
|
||||||
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
|
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
|
||||||
format!(
|
DiagStyledString::normal(format!(
|
||||||
" (trait associated opaque type at <{}:{}:{}>)",
|
" (trait associated opaque type at <{}:{}:{}>)",
|
||||||
sm.filename_for_diagnostics(&pos.file.name),
|
sm.filename_for_diagnostics(&pos.file.name),
|
||||||
pos.line,
|
pos.line,
|
||||||
pos.col.to_usize() + 1,
|
pos.col.to_usize() + 1,
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
|
(true, _) => {
|
||||||
(false, _) => "".to_string(),
|
let mut s = DiagStyledString::normal(" (");
|
||||||
|
s.push_highlighted(ty.sort_string(self.tcx));
|
||||||
|
s.push_normal(")");
|
||||||
|
s
|
||||||
|
}
|
||||||
|
(false, _) => DiagStyledString::normal(""),
|
||||||
};
|
};
|
||||||
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|
||||||
|| (exp_found.is_some_and(|ef| {
|
|| (exp_found.is_some_and(|ef| {
|
||||||
|
@ -1764,26 +1774,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
if let Some(ExpectedFound { found: found_ty, .. }) = exp_found {
|
if let Some(ExpectedFound { found: found_ty, .. }) = exp_found
|
||||||
|
&& !self.tcx.ty_is_opaque_future(found_ty)
|
||||||
|
{
|
||||||
// `Future` is a special opaque type that the compiler
|
// `Future` is a special opaque type that the compiler
|
||||||
// will try to hide in some case such as `async fn`, so
|
// will try to hide in some case such as `async fn`, so
|
||||||
// to make an error more use friendly we will
|
// to make an error more use friendly we will
|
||||||
// avoid to suggest a mismatch type with a
|
// avoid to suggest a mismatch type with a
|
||||||
// type that the user usually are not using
|
// type that the user usually are not using
|
||||||
// directly such as `impl Future<Output = u8>`.
|
// directly such as `impl Future<Output = u8>`.
|
||||||
if !self.tcx.ty_is_opaque_future(found_ty) {
|
|
||||||
diag.note_expected_found_extra(
|
diag.note_expected_found_extra(
|
||||||
&expected_label,
|
&expected_label,
|
||||||
expected,
|
expected,
|
||||||
&found_label,
|
&found_label,
|
||||||
found,
|
found,
|
||||||
&sort_string(values.expected),
|
sort_string(values.expected),
|
||||||
&sort_string(values.found),
|
sort_string(values.found),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
debug!(
|
debug!(
|
||||||
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
|
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
|
||||||
|
|
|
@ -712,8 +712,8 @@ impl String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`]
|
/// Decode a native endian UTF-16–encoded vector `v` into a `String`,
|
||||||
/// if `v` contains any invalid data.
|
/// returning [`Err`] if `v` contains any invalid data.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -745,8 +745,8 @@ impl String {
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a UTF-16–encoded slice `v` into a `String`, replacing
|
/// Decode a native endian UTF-16–encoded slice `v` into a `String`,
|
||||||
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
|
/// replacing invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
|
||||||
///
|
///
|
||||||
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
|
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
|
||||||
/// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8
|
/// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8
|
||||||
|
@ -777,8 +777,8 @@ impl String {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a UTF-16LE–encoded vector `v` into a `String`, returning [`Err`]
|
/// Decode a UTF-16LE–encoded vector `v` into a `String`,
|
||||||
/// if `v` contains any invalid data.
|
/// returning [`Err`] if `v` contains any invalid data.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -852,8 +852,8 @@ impl String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a UTF-16BE–encoded vector `v` into a `String`, returning [`Err`]
|
/// Decode a UTF-16BE–encoded vector `v` into a `String`,
|
||||||
/// if `v` contains any invalid data.
|
/// returning [`Err`] if `v` contains any invalid data.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -92,7 +92,7 @@ impl char {
|
||||||
#[stable(feature = "assoc_char_consts", since = "1.52.0")]
|
#[stable(feature = "assoc_char_consts", since = "1.52.0")]
|
||||||
pub const UNICODE_VERSION: (u8, u8, u8) = crate::unicode::UNICODE_VERSION;
|
pub const UNICODE_VERSION: (u8, u8, u8) = crate::unicode::UNICODE_VERSION;
|
||||||
|
|
||||||
/// Creates an iterator over the UTF-16 encoded code points in `iter`,
|
/// Creates an iterator over the native endian UTF-16 encoded code points in `iter`,
|
||||||
/// returning unpaired surrogates as `Err`s.
|
/// returning unpaired surrogates as `Err`s.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -704,7 +704,7 @@ impl char {
|
||||||
unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
|
unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes this character as UTF-16 into the provided `u16` buffer,
|
/// Encodes this character as native endian UTF-16 into the provided `u16` buffer,
|
||||||
/// and then returns the subslice of the buffer that contains the encoded character.
|
/// and then returns the subslice of the buffer that contains the encoded character.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
@ -1828,7 +1828,7 @@ pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
|
||||||
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
|
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes a raw `u32` value as UTF-16 into the provided `u16` buffer,
|
/// Encodes a raw `u32` value as native endian UTF-16 into the provided `u16` buffer,
|
||||||
/// and then returns the subslice of the buffer that contains the encoded character.
|
/// and then returns the subslice of the buffer that contains the encoded character.
|
||||||
///
|
///
|
||||||
/// Unlike `char::encode_utf16`, this method also handles codepoints in the surrogate range.
|
/// Unlike `char::encode_utf16`, this method also handles codepoints in the surrogate range.
|
||||||
|
|
|
@ -78,7 +78,11 @@ pub mod simd;
|
||||||
use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
|
use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
|
||||||
|
|
||||||
#[stable(feature = "drop_in_place", since = "1.8.0")]
|
#[stable(feature = "drop_in_place", since = "1.8.0")]
|
||||||
#[rustc_allowed_through_unstable_modules]
|
#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)]
|
||||||
|
#[cfg_attr(
|
||||||
|
not(bootstrap),
|
||||||
|
rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"
|
||||||
|
)]
|
||||||
#[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
|
#[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||||
|
|
|
@ -1831,32 +1831,4 @@ pub(crate) mod builtin {
|
||||||
pub macro deref($pat:pat) {
|
pub macro deref($pat:pat) {
|
||||||
builtin # deref($pat)
|
builtin # deref($pat)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive macro for `rustc-serialize`. Should not be used in new code.
|
|
||||||
#[rustc_builtin_macro]
|
|
||||||
#[unstable(
|
|
||||||
feature = "rustc_encodable_decodable",
|
|
||||||
issue = "none",
|
|
||||||
soft,
|
|
||||||
reason = "derive macro for `rustc-serialize`; should not be used in new code"
|
|
||||||
)]
|
|
||||||
#[deprecated(since = "1.52.0", note = "rustc-serialize is deprecated and no longer supported")]
|
|
||||||
#[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
|
|
||||||
pub macro RustcDecodable($item:item) {
|
|
||||||
/* compiler built-in */
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Derive macro for `rustc-serialize`. Should not be used in new code.
|
|
||||||
#[rustc_builtin_macro]
|
|
||||||
#[unstable(
|
|
||||||
feature = "rustc_encodable_decodable",
|
|
||||||
issue = "none",
|
|
||||||
soft,
|
|
||||||
reason = "derive macro for `rustc-serialize`; should not be used in new code"
|
|
||||||
)]
|
|
||||||
#[deprecated(since = "1.52.0", note = "rustc-serialize is deprecated and no longer supported")]
|
|
||||||
#[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
|
|
||||||
pub macro RustcEncodable($item:item) {
|
|
||||||
/* compiler built-in */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,6 @@ mod common;
|
||||||
pub mod v1 {
|
pub mod v1 {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use super::common::*;
|
pub use super::common::*;
|
||||||
|
|
||||||
// Do not `doc(inline)` these `doc(hidden)` items.
|
|
||||||
#[unstable(
|
|
||||||
feature = "rustc_encodable_decodable",
|
|
||||||
issue = "none",
|
|
||||||
soft,
|
|
||||||
reason = "derive macro for `rustc-serialize`; should not be used in new code"
|
|
||||||
)]
|
|
||||||
#[allow(deprecated)]
|
|
||||||
pub use crate::macros::builtin::{RustcDecodable, RustcEncodable};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 2015 version of the core prelude.
|
/// The 2015 version of the core prelude.
|
||||||
|
|
|
@ -1108,7 +1108,8 @@ impl str {
|
||||||
LinesAny(self.lines())
|
LinesAny(self.lines())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator of `u16` over the string encoded as UTF-16.
|
/// Returns an iterator of `u16` over the string encoded
|
||||||
|
/// as native endian UTF-16 (without byte-order mark).
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -120,16 +120,6 @@ mod common;
|
||||||
pub mod v1 {
|
pub mod v1 {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use super::common::*;
|
pub use super::common::*;
|
||||||
|
|
||||||
// Do not `doc(inline)` these `doc(hidden)` items.
|
|
||||||
#[unstable(
|
|
||||||
feature = "rustc_encodable_decodable",
|
|
||||||
issue = "none",
|
|
||||||
soft,
|
|
||||||
reason = "derive macro for `rustc-serialize`; should not be used in new code"
|
|
||||||
)]
|
|
||||||
#[allow(deprecated)]
|
|
||||||
pub use core::prelude::v1::{RustcDecodable, RustcEncodable};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 2015 version of the prelude of The Rust Standard Library.
|
/// The 2015 version of the prelude of The Rust Standard Library.
|
||||||
|
|
|
@ -5,9 +5,7 @@ use std::{fmt, iter};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use rustc_abi::{ExternAbi, VariantIdx};
|
use rustc_abi::{ExternAbi, VariantIdx};
|
||||||
use rustc_attr_parsing::{
|
use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince};
|
||||||
AllowedThroughUnstableModules, ConstStability, Deprecation, Stability, StableSince,
|
|
||||||
};
|
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
|
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
|
||||||
|
@ -411,15 +409,9 @@ impl Item {
|
||||||
..
|
..
|
||||||
} = stab.level
|
} = stab.level
|
||||||
{
|
{
|
||||||
let note = match note {
|
|
||||||
AllowedThroughUnstableModules::WithDeprecation(note) => Some(note),
|
|
||||||
// FIXME: Would be better to say *something* here about the *path* being
|
|
||||||
// deprecated rather than the item.
|
|
||||||
AllowedThroughUnstableModules::WithoutDeprecation => None,
|
|
||||||
};
|
|
||||||
Some(Deprecation {
|
Some(Deprecation {
|
||||||
since: rustc_attr_parsing::DeprecatedSince::Unspecified,
|
since: rustc_attr_parsing::DeprecatedSince::Unspecified,
|
||||||
note,
|
note: Some(note),
|
||||||
suggestion: None,
|
suggestion: None,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -788,7 +788,7 @@ don't hesitate to ask on [Zulip] or in the issue/PR.
|
||||||
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
|
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
|
||||||
[let-chains]: https://github.com/rust-lang/rust/pull/94927
|
[let-chains]: https://github.com/rust-lang/rust/pull/94927
|
||||||
[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
|
[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
|
||||||
[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
|
[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
|
||||||
[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
|
[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
|
||||||
[applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
|
[applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
|
||||||
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
|
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
|
||||||
|
|
|
@ -218,7 +218,7 @@ functions to deal with macros:
|
||||||
> context. And so just using `span.from_expansion()` is often good enough.
|
> context. And so just using `span.from_expansion()` is often good enough.
|
||||||
|
|
||||||
|
|
||||||
- `in_external_macro(span)`: detect if the given span is from a macro defined in
|
- `span.in_external_macro(sm)`: detect if the given span is from a macro defined in
|
||||||
a foreign crate. If you want the lint to work with macro-generated code, this
|
a foreign crate. If you want the lint to work with macro-generated code, this
|
||||||
is the next line of defense to avoid macros not defined in the current crate.
|
is the next line of defense to avoid macros not defined in the current crate.
|
||||||
It doesn't make sense to lint code that the coder can't change.
|
It doesn't make sense to lint code that the coder can't change.
|
||||||
|
@ -227,15 +227,13 @@ functions to deal with macros:
|
||||||
crates
|
crates
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
|
|
||||||
use a_crate_with_macros::foo;
|
use a_crate_with_macros::foo;
|
||||||
|
|
||||||
// `foo` is defined in `a_crate_with_macros`
|
// `foo` is defined in `a_crate_with_macros`
|
||||||
foo!("bar");
|
foo!("bar");
|
||||||
|
|
||||||
// if we lint the `match` of `foo` call and test its span
|
// if we lint the `match` of `foo` call and test its span
|
||||||
assert_eq!(in_external_macro(cx.sess(), match_span), true);
|
assert_eq!(match_span.in_external_macro(cx.sess().source_map()), true);
|
||||||
```
|
```
|
||||||
|
|
||||||
- `span.ctxt()`: the span's context represents whether it is from expansion, and
|
- `span.ctxt()`: the span's context represents whether it is from expansion, and
|
||||||
|
|
|
@ -120,7 +120,7 @@ assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());
|
||||||
|
|
||||||
### The `in_external_macro` function
|
### The `in_external_macro` function
|
||||||
|
|
||||||
`rustc_middle::lint` provides a function ([`in_external_macro`]) that can
|
`Span` provides a method ([`in_external_macro`]) that can
|
||||||
detect if the given span is from a macro defined in a foreign crate.
|
detect if the given span is from a macro defined in a foreign crate.
|
||||||
|
|
||||||
Therefore, if we really want a new lint to work with macro-generated code,
|
Therefore, if we really want a new lint to work with macro-generated code,
|
||||||
|
@ -144,7 +144,7 @@ Also assume that we get the corresponding variable `foo_span` for the
|
||||||
results in `true` (note that `cx` can be `EarlyContext` or `LateContext`):
|
results in `true` (note that `cx` can be `EarlyContext` or `LateContext`):
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
if in_external_macro(cx.sess(), foo_span) {
|
if foo_span.in_external_macro(cx.sess().source_map()) {
|
||||||
// We should ignore macro from a foreign crate.
|
// We should ignore macro from a foreign crate.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,6 @@ if in_external_macro(cx.sess(), foo_span) {
|
||||||
[`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
|
[`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
|
||||||
[expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
|
[expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
|
||||||
[`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
|
[`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
|
||||||
[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
|
[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
|
||||||
[Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
|
[Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
|
||||||
[SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
|
[SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
|
||||||
|
|
|
@ -5,7 +5,6 @@ use clippy_utils::source::{trim_span, walk_span_to_context};
|
||||||
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
|
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -45,7 +44,7 @@ impl EarlyLintPass for AlmostCompleteRange {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
|
||||||
if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
|
if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
|
||||||
&& is_incomplete_range(start, end)
|
&& is_incomplete_range(start, end)
|
||||||
&& !in_external_macro(cx.sess(), e.span)
|
&& !e.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
|
@ -74,7 +73,7 @@ impl EarlyLintPass for AlmostCompleteRange {
|
||||||
if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
|
if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
|
||||||
&& matches!(kind.node, RangeEnd::Excluded)
|
&& matches!(kind.node, RangeEnd::Excluded)
|
||||||
&& is_incomplete_range(start, end)
|
&& is_incomplete_range(start, end)
|
||||||
&& !in_external_macro(cx.sess(), p.span)
|
&& !p.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_hir::{
|
||||||
Variant, VariantData,
|
Variant, VariantData,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -248,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
|
||||||
ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
|
ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
|
||||||
let mut cur_v: Option<&Variant<'_>> = None;
|
let mut cur_v: Option<&Variant<'_>> = None;
|
||||||
for variant in enum_def.variants {
|
for variant in enum_def.variants {
|
||||||
if in_external_macro(cx.sess(), variant.span) {
|
if variant.span.in_external_macro(cx.sess().source_map()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
|
||||||
ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
|
ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
|
||||||
let mut cur_f: Option<&FieldDef<'_>> = None;
|
let mut cur_f: Option<&FieldDef<'_>> = None;
|
||||||
for field in *fields {
|
for field in *fields {
|
||||||
if in_external_macro(cx.sess(), field.span) {
|
if field.span.in_external_macro(cx.sess().source_map()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
|
||||||
let mut cur_t: Option<&TraitItemRef> = None;
|
let mut cur_t: Option<&TraitItemRef> = None;
|
||||||
|
|
||||||
for item in *item_ref {
|
for item in *item_ref {
|
||||||
if in_external_macro(cx.sess(), item.span) {
|
if item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
|
||||||
let mut cur_t: Option<&ImplItemRef> = None;
|
let mut cur_t: Option<&ImplItemRef> = None;
|
||||||
|
|
||||||
for item in trait_impl.items {
|
for item in trait_impl.items {
|
||||||
if in_external_macro(cx.sess(), item.span) {
|
if item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
|
||||||
// as no sorting by source map/line of code has to be applied.
|
// as no sorting by source map/line of code has to be applied.
|
||||||
//
|
//
|
||||||
for item in items {
|
for item in items {
|
||||||
if in_external_macro(cx.sess(), item.span) {
|
if item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -49,7 +48,7 @@ declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
|
||||||
impl<'tcx> LateLintPass<'tcx> for AsConversions {
|
impl<'tcx> LateLintPass<'tcx> for AsConversions {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
|
||||||
if let ExprKind::Cast(_, _) = expr.kind
|
if let ExprKind::Cast(_, _) = expr.kind
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& !is_from_proc_macro(cx, expr)
|
&& !is_from_proc_macro(cx, expr)
|
||||||
{
|
{
|
||||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||||
|
|
|
@ -4,11 +4,10 @@ use clippy_utils::is_from_proc_macro;
|
||||||
use rustc_ast::{AttrStyle, Attribute};
|
use rustc_ast::{AttrStyle, Attribute};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, LintContext};
|
use rustc_lint::{EarlyContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
|
|
||||||
// Separate each crate's features.
|
// Separate each crate's features.
|
||||||
pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {
|
pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {
|
||||||
if !in_external_macro(cx.sess(), attr.span)
|
if !attr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let AttrStyle::Outer = attr.style
|
&& let AttrStyle::Outer = attr.style
|
||||||
&& let Some(ident) = attr.ident()
|
&& let Some(ident) = attr.ident()
|
||||||
&& !is_from_proc_macro(cx, attr)
|
&& !is_from_proc_macro(cx, attr)
|
||||||
|
|
|
@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
use rustc_ast::{MetaItemInner, MetaItemKind};
|
use rustc_ast::{MetaItemInner, MetaItemKind};
|
||||||
use rustc_lint::{EarlyContext, LintContext};
|
use rustc_lint::{EarlyContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ pub(super) fn check<'cx>(cx: &EarlyContext<'cx>, name: Symbol, items: &[MetaItem
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the attribute is in an external macro and therefore out of the developer's control
|
// Check if the attribute is in an external macro and therefore out of the developer's control
|
||||||
if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, attr) {
|
if attr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, attr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,13 @@ use clippy_utils::source::{SpanRangeExt, first_line_of_span};
|
||||||
use rustc_ast::{Attribute, Item, ItemKind};
|
use rustc_ast::{Attribute, Item, ItemKind};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, LintContext};
|
use rustc_lint::{EarlyContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
|
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
|
||||||
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
|
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
|
||||||
|
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if in_external_macro(cx.sess(), attr.span) {
|
if attr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(lint_list) = &attr.meta_item_list() {
|
if let Some(lint_list) = &attr.meta_item_list() {
|
||||||
|
|
|
@ -4,7 +4,6 @@ use clippy_utils::{higher, is_from_proc_macro};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
|
use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -54,7 +53,7 @@ const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression conditio
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
|
impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if in_external_macro(cx.sess(), expr.span) {
|
if expr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_hir::def::Res;
|
||||||
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
|
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
|
||||||
use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LetStmt, Node, QPath, Ty, TyKind};
|
use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LetStmt, Node, QPath, Ty, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ impl LateLintPass<'_> for BoxDefault {
|
||||||
// This is the `T::default()` (or default equivalent) of `Box::new(T::default())`
|
// This is the `T::default()` (or default equivalent) of `Box::new(T::default())`
|
||||||
&& let ExprKind::Call(arg_path, _) = arg.kind
|
&& let ExprKind::Call(arg_path, _) = arg.kind
|
||||||
// And we are not in a foreign crate's macro
|
// And we are not in a foreign crate's macro
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
// And the argument expression has the same context as the outer call expression
|
// And the argument expression has the same context as the outer call expression
|
||||||
// or that we are inside a `vec!` macro expansion
|
// or that we are inside a `vec!` macro expansion
|
||||||
&& (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))
|
&& (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))
|
||||||
|
|
|
@ -29,7 +29,6 @@ use clippy_utils::is_hir_ty_cfg_dependant;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
use clippy_utils::msrvs::{self, Msrv};
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -796,7 +795,7 @@ impl_lint_pass!(Casts => [
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for Casts {
|
impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if in_external_macro(cx.sess(), expr.span) {
|
if expr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp};
|
use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp};
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
|
use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
@ -142,7 +141,7 @@ pub(super) fn check<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
|
if cast_from.kind() == cast_to.kind() && !expr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
if let Some(id) = path_to_local(cast_expr)
|
if let Some(id) = path_to_local(cast_expr)
|
||||||
&& !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
|
&& !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,6 @@ use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};
|
use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -64,7 +63,7 @@ impl LateLintPass<'_> for CheckedConversions {
|
||||||
},
|
},
|
||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
&& !in_external_macro(cx.sess(), item.span)
|
&& !item.span.in_external_macro(cx.sess().source_map())
|
||||||
&& !is_in_const_context(cx)
|
&& !is_in_const_context(cx)
|
||||||
&& self.msrv.meets(msrvs::TRY_FROM)
|
&& self.msrv.meets(msrvs::TRY_FROM)
|
||||||
&& let Some(cv) = match op2 {
|
&& let Some(cv) = match op2 {
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, Node};
|
use rustc_hir::{Expr, ExprKind, Node};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::{Span, SyntaxContext, sym};
|
use rustc_span::{Span, SyntaxContext, sym};
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ impl LateLintPass<'_> for DbgMacro {
|
||||||
|
|
||||||
if cur_syntax_ctxt != self.prev_ctxt &&
|
if cur_syntax_ctxt != self.prev_ctxt &&
|
||||||
let Some(macro_call) = first_dbg_macro_in_expansion(cx, expr.span) &&
|
let Some(macro_call) = first_dbg_macro_in_expansion(cx, expr.span) &&
|
||||||
!in_external_macro(cx.sess(), macro_call.span) &&
|
!macro_call.span.in_external_macro(cx.sess().source_map()) &&
|
||||||
self.checked_dbg_call_site.insert(macro_call.span) &&
|
self.checked_dbg_call_site.insert(macro_call.span) &&
|
||||||
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
|
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
|
||||||
!(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
|
!(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_hir::{
|
||||||
StructTailExpr,
|
StructTailExpr,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
|
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -86,7 +85,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
/// Check whether a passed literal has potential to cause fallback or not.
|
/// Check whether a passed literal has potential to cause fallback or not.
|
||||||
fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>, emit_hir_id: HirId) {
|
fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>, emit_hir_id: HirId) {
|
||||||
if !in_external_macro(self.cx.sess(), lit.span)
|
if !lit.span.in_external_macro(self.cx.sess().source_map())
|
||||||
&& matches!(self.ty_bounds.last(), Some(ExplicitTyBound(false)))
|
&& matches!(self.ty_bounds.last(), Some(ExplicitTyBound(false)))
|
||||||
&& matches!(
|
&& matches!(
|
||||||
lit.node,
|
lit.node,
|
||||||
|
|
|
@ -22,7 +22,6 @@ use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
|
use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_resolve::rustdoc::{
|
use rustc_resolve::rustdoc::{
|
||||||
DocFragment, add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range,
|
DocFragment, add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range,
|
||||||
|
@ -675,7 +674,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ItemKind::Fn { sig, body: body_id, .. } => {
|
ItemKind::Fn { sig, body: body_id, .. } => {
|
||||||
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id())
|
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id())
|
||||||
|| in_external_macro(cx.tcx.sess, item.span))
|
|| item.span.in_external_macro(cx.tcx.sess.source_map()))
|
||||||
{
|
{
|
||||||
let body = cx.tcx.hir().body(body_id);
|
let body = cx.tcx.hir().body(body_id);
|
||||||
|
|
||||||
|
@ -711,7 +710,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
|
||||||
},
|
},
|
||||||
Node::TraitItem(trait_item) => {
|
Node::TraitItem(trait_item) => {
|
||||||
if let TraitItemKind::Fn(sig, ..) = trait_item.kind
|
if let TraitItemKind::Fn(sig, ..) = trait_item.kind
|
||||||
&& !in_external_macro(cx.tcx.sess, trait_item.span)
|
&& !trait_item.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
{
|
{
|
||||||
missing_headers::check(
|
missing_headers::check(
|
||||||
cx,
|
cx,
|
||||||
|
@ -726,7 +725,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
|
||||||
},
|
},
|
||||||
Node::ImplItem(impl_item) => {
|
Node::ImplItem(impl_item) => {
|
||||||
if let ImplItemKind::Fn(sig, body_id) = impl_item.kind
|
if let ImplItemKind::Fn(sig, body_id) = impl_item.kind
|
||||||
&& !in_external_macro(cx.tcx.sess, impl_item.span)
|
&& !impl_item.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
&& !is_trait_impl_item(cx, impl_item.hir_id())
|
&& !is_trait_impl_item(cx, impl_item.hir_id())
|
||||||
{
|
{
|
||||||
let body = cx.tcx.hir().body(body_id);
|
let body = cx.tcx.hir().body(body_id);
|
||||||
|
@ -791,7 +790,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
|
||||||
|
|
||||||
let (fragments, _) = attrs_to_doc_fragments(
|
let (fragments, _) = attrs_to_doc_fragments(
|
||||||
attrs.iter().filter_map(|attr| {
|
attrs.iter().filter_map(|attr| {
|
||||||
if in_external_macro(cx.sess(), attr.span) {
|
if attr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((attr, None))
|
Some((attr, None))
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use rustc_ast::ast::{Expr, ExprKind};
|
use rustc_ast::ast::{Expr, ExprKind};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -50,7 +49,7 @@ impl EarlyLintPass for ElseIfWithoutElse {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {
|
||||||
if let ExprKind::If(_, _, Some(ref els)) = item.kind
|
if let ExprKind::If(_, _, Some(ref els)) = item.kind
|
||||||
&& let ExprKind::If(_, _, None) = els.kind
|
&& let ExprKind::If(_, _, None) = els.kind
|
||||||
&& !in_external_macro(cx.sess(), item.span)
|
&& !item.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
|
|
|
@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::is_lint_allowed;
|
use clippy_utils::is_lint_allowed;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
|
@ -119,7 +118,7 @@ impl LateLintPass<'_> for EndianBytes {
|
||||||
},
|
},
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
if !in_external_macro(cx.sess(), expr.span)
|
if !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let ty = cx.typeck_results().expr_ty(ty_expr)
|
&& let ty = cx.typeck_results().expr_ty(ty_expr)
|
||||||
&& ty.is_primitive_ty()
|
&& ty.is_primitive_ty()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,6 @@ use clippy_utils::ty::implements_trait;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, Pat, PatKind};
|
use rustc_hir::{Expr, ExprKind, Pat, PatKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
if let ExprKind::Let(let_expr) = expr.kind
|
if let ExprKind::Let(let_expr) = expr.kind
|
||||||
&& unary_pattern(let_expr.pat)
|
&& unary_pattern(let_expr.pat)
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
|
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
|
||||||
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
|
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_ast::node_id::NodeSet;
|
||||||
use rustc_ast::visit::{Visitor, walk_block, walk_item};
|
use rustc_ast::visit::{Visitor, walk_block, walk_item};
|
||||||
use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};
|
use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -125,7 +124,7 @@ struct NestingVisitor<'conf, 'cx> {
|
||||||
|
|
||||||
impl NestingVisitor<'_, '_> {
|
impl NestingVisitor<'_, '_> {
|
||||||
fn check_indent(&mut self, span: Span, id: NodeId) -> bool {
|
fn check_indent(&mut self, span: Span, id: NodeId) -> bool {
|
||||||
if self.nest_level > self.conf.excessive_nesting_threshold && !in_external_macro(self.cx.sess(), span) {
|
if self.nest_level > self.conf.excessive_nesting_threshold && !span.in_external_macro(self.cx.sess().source_map()) {
|
||||||
self.conf.nodes.insert(id);
|
self.conf.nodes.insert(id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -10,7 +10,6 @@ use rustc_hir::{
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
|
@ -261,7 +260,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
|
||||||
&& !generics.params.is_empty()
|
&& !generics.params.is_empty()
|
||||||
&& !is_empty_body(cx, body_id)
|
&& !is_empty_body(cx, body_id)
|
||||||
&& (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
|
&& (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
|
||||||
&& !in_external_macro(cx.sess(), item.span)
|
&& !item.span.in_external_macro(cx.sess().source_map())
|
||||||
&& !is_from_proc_macro(cx, item)
|
&& !is_from_proc_macro(cx, item)
|
||||||
{
|
{
|
||||||
let mut walker = TypeWalker::new(cx, generics);
|
let mut walker = TypeWalker::new(cx, generics);
|
||||||
|
@ -277,7 +276,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
|
||||||
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
|
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
|
||||||
&& !is_empty_body(cx, body_id)
|
&& !is_empty_body(cx, body_id)
|
||||||
&& (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
|
&& (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
|
||||||
&& !in_external_macro(cx.sess(), item.span)
|
&& !item.span.in_external_macro(cx.sess().source_map())
|
||||||
&& !is_from_proc_macro(cx, item)
|
&& !is_from_proc_macro(cx, item)
|
||||||
{
|
{
|
||||||
let mut walker = TypeWalker::new(cx, item.generics);
|
let mut walker = TypeWalker::new(cx, item.generics);
|
||||||
|
|
|
@ -3,7 +3,6 @@ use clippy_utils::is_span_if;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
|
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -202,7 +201,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
|
||||||
if let ExprKind::If(_, then, Some(else_)) = &expr.kind
|
if let ExprKind::If(_, then, Some(else_)) = &expr.kind
|
||||||
&& (is_block(else_) || is_if(else_))
|
&& (is_block(else_) || is_if(else_))
|
||||||
&& !then.span.from_expansion() && !else_.span.from_expansion()
|
&& !then.span.from_expansion() && !else_.span.from_expansion()
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
|
|
||||||
// workaround for rust-lang/rust#43081
|
// workaround for rust-lang/rust#43081
|
||||||
&& expr.span.lo().0 != 0 && expr.span.hi().0 != 0
|
&& expr.span.lo().0 != 0 && expr.span.hi().0 != 0
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_hir::def_id::DefIdSet;
|
||||||
use rustc_hir::{self as hir, Attribute, QPath};
|
use rustc_hir::{self as hir, Attribute, QPath};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
|
||||||
|
@ -107,7 +106,7 @@ fn check_needless_must_use(
|
||||||
attrs: &[Attribute],
|
attrs: &[Attribute],
|
||||||
sig: &FnSig<'_>,
|
sig: &FnSig<'_>,
|
||||||
) {
|
) {
|
||||||
if in_external_macro(cx.sess(), item_span) {
|
if item_span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if returns_unit(decl) {
|
if returns_unit(decl) {
|
||||||
|
@ -185,7 +184,7 @@ fn check_must_use_candidate<'tcx>(
|
||||||
) {
|
) {
|
||||||
if has_mutable_arg(cx, body)
|
if has_mutable_arg(cx, body)
|
||||||
|| mutates_static(cx, body)
|
|| mutates_static(cx, body)
|
||||||
|| in_external_macro(cx.sess(), item_span)
|
|| item_span.in_external_macro(cx.sess().source_map())
|
||||||
|| returns_unit(decl)
|
|| returns_unit(decl)
|
||||||
|| !cx.effective_visibilities.is_exported(item_id.def_id)
|
|| !cx.effective_visibilities.is_exported(item_id.def_id)
|
||||||
|| is_must_use_ty(cx, return_ty(cx, item_id))
|
|| is_must_use_ty(cx, return_ty(cx, item_id))
|
||||||
|
|
|
@ -2,7 +2,6 @@ use clippy_utils::msrvs::{self, Msrv};
|
||||||
use rustc_errors::Diag;
|
use rustc_errors::Diag;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ fn result_err_ty<'tcx>(
|
||||||
id: hir::def_id::LocalDefId,
|
id: hir::def_id::LocalDefId,
|
||||||
item_span: Span,
|
item_span: Span,
|
||||||
) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
|
) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
|
||||||
if !in_external_macro(cx.sess(), item_span)
|
if !item_span.in_external_macro(cx.sess().source_map())
|
||||||
&& let hir::FnRetTy::Return(hir_ty) = decl.output
|
&& let hir::FnRetTy::Return(hir_ty) = decl.output
|
||||||
&& let ty = cx
|
&& let ty = cx
|
||||||
.tcx
|
.tcx
|
||||||
|
|
|
@ -3,7 +3,6 @@ use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use super::TOO_MANY_LINES;
|
use super::TOO_MANY_LINES;
|
||||||
|
@ -17,7 +16,7 @@ pub(super) fn check_fn(
|
||||||
) {
|
) {
|
||||||
// Closures must be contained in a parent body, which will be checked for `too_many_lines`.
|
// Closures must be contained in a parent body, which will be checked for `too_many_lines`.
|
||||||
// Don't check closures for `too_many_lines` to avoid duplicated lints.
|
// Don't check closures for `too_many_lines` to avoid duplicated lints.
|
||||||
if matches!(kind, FnKind::Closure) || in_external_macro(cx.sess(), span) {
|
if matches!(kind, FnKind::Closure) || span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -79,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
||||||
&& is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
|
&& is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
|
||||||
&& !is_else_clause(cx.tcx, expr)
|
&& !is_else_clause(cx.tcx, expr)
|
||||||
&& !is_in_const_context(cx)
|
&& !is_in_const_context(cx)
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& self.msrv.meets(msrvs::BOOL_THEN)
|
&& self.msrv.meets(msrvs::BOOL_THEN)
|
||||||
&& !contains_return(then_block.stmts)
|
&& !contains_return(then_block.stmts)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
|
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::{Span, SyntaxContext};
|
use rustc_span::{Span, SyntaxContext};
|
||||||
|
@ -227,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
|
||||||
) {
|
) {
|
||||||
if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))
|
if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))
|
||||||
|| !span.eq_ctxt(body.value.span)
|
|| !span.eq_ctxt(body.value.span)
|
||||||
|| in_external_macro(cx.sess(), span)
|
|| span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use clippy_utils::diagnostics::span_lint_hir;
|
use clippy_utils::diagnostics::span_lint_hir;
|
||||||
use rustc_hir::{Block, ItemKind, StmtKind};
|
use rustc_hir::{Block, ItemKind, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -70,7 +69,7 @@ impl LateLintPass<'_> for ItemsAfterStatements {
|
||||||
// Don't use `next` due to the complex filter chain.
|
// Don't use `next` due to the complex filter chain.
|
||||||
.for_each(|item| {
|
.for_each(|item| {
|
||||||
// Only do the macro check once, but delay it until it's needed.
|
// Only do the macro check once, but delay it until it's needed.
|
||||||
if !*in_external.get_or_insert_with(|| in_external_macro(cx.sess(), block.span)) {
|
if !*in_external.get_or_insert_with(|| block.span.in_external_macro(cx.sess().source_map())) {
|
||||||
span_lint_hir(
|
span_lint_hir(
|
||||||
cx,
|
cx,
|
||||||
ITEMS_AFTER_STATEMENTS,
|
ITEMS_AFTER_STATEMENTS,
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_ast::Mutability;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
|
use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
@ -131,7 +130,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
|
||||||
&& trait_ref
|
&& trait_ref
|
||||||
.trait_def_id()
|
.trait_def_id()
|
||||||
.is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did))
|
.is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did))
|
||||||
&& !in_external_macro(cx.sess(), item.span)
|
&& !item.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
|
&& let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
|
||||||
&& let expected_method_name = match mtbl {
|
&& let expected_method_name = match mtbl {
|
||||||
Mutability::Mut => sym::iter_mut,
|
Mutability::Mut => sym::iter_mut,
|
||||||
|
@ -193,7 +192,7 @@ impl {self_ty_without_ref} {{
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !in_external_macro(cx.sess(), item.span)
|
if !item.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let ImplItemKind::Fn(sig, _) = item.kind
|
&& let ImplItemKind::Fn(sig, _) = item.kind
|
||||||
&& let FnRetTy::Return(ret) = sig.decl.output
|
&& let FnRetTy::Return(ret) = sig.decl.output
|
||||||
&& is_nameable_in_impl_trait(ret)
|
&& is_nameable_in_impl_trait(ret)
|
||||||
|
|
|
@ -5,7 +5,6 @@ use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Item, ItemKind};
|
use rustc_hir::{Item, ItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -78,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
|
||||||
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
|
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
|
||||||
&& let ty::Adt(adt, subst) = ty.kind()
|
&& let ty::Adt(adt, subst) = ty.kind()
|
||||||
&& adt.variants().len() > 1
|
&& adt.variants().len() > 1
|
||||||
&& !in_external_macro(cx.tcx.sess, item.span)
|
&& !item.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
{
|
{
|
||||||
let variants_size = AdtVariantInfo::new(cx, *adt, subst);
|
let variants_size = AdtVariantInfo::new(cx, *adt, subst);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
|
use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
use rustc_span::{Symbol, sym};
|
use rustc_span::{Symbol, sym};
|
||||||
|
@ -54,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
|
||||||
// so lint on the `use` statement directly.
|
// so lint on the `use` statement directly.
|
||||||
if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
|
if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
|
||||||
&& self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
|
&& self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
|
||||||
&& !in_external_macro(cx.sess(), item.span)
|
&& !item.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let Some(def_id) = path.res[0].opt_def_id()
|
&& let Some(def_id) = path.res[0].opt_def_id()
|
||||||
{
|
{
|
||||||
let module = if is_integer_module(cx, def_id) {
|
let module = if is_integer_module(cx, def_id) {
|
||||||
|
@ -139,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
|
if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& !is_from_proc_macro(cx, expr)
|
&& !is_from_proc_macro(cx, expr)
|
||||||
{
|
{
|
||||||
span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
|
span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
|
||||||
|
|
|
@ -3,7 +3,6 @@ use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
|
||||||
use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
|
use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
|
||||||
use rustc_hir::{LetStmt, LocalSource, PatKind};
|
use rustc_hir::{LetStmt, LocalSource, PatKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{GenericArgKind, IsSuggestable};
|
use rustc_middle::ty::{GenericArgKind, IsSuggestable};
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::{BytePos, Span};
|
use rustc_span::{BytePos, Span};
|
||||||
|
@ -141,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||||
if matches!(local.source, LocalSource::Normal)
|
if matches!(local.source, LocalSource::Normal)
|
||||||
&& let PatKind::Wild = local.pat.kind
|
&& let PatKind::Wild = local.pat.kind
|
||||||
&& let Some(init) = local.init
|
&& let Some(init) = local.init
|
||||||
&& !in_external_macro(cx.tcx.sess, local.span)
|
&& !local.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
{
|
{
|
||||||
let init_ty = cx.typeck_results().expr_ty(init);
|
let init_ty = cx.typeck_results().expr_ty(init);
|
||||||
let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
|
let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
|
||||||
|
|
|
@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
use rustc_hir::{LetStmt, TyKind};
|
use rustc_hir::{LetStmt, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -30,7 +29,7 @@ impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
|
||||||
if let Some(ty) = local.ty // Ensure that it has a type defined
|
if let Some(ty) = local.ty // Ensure that it has a type defined
|
||||||
&& let TyKind::Infer(()) = &ty.kind // that type is '_'
|
&& let TyKind::Infer(()) = &ty.kind // that type is '_'
|
||||||
&& local.span.eq_ctxt(ty.span)
|
&& local.span.eq_ctxt(ty.span)
|
||||||
&& !in_external_macro(cx.tcx.sess, local.span)
|
&& !local.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
&& !is_from_proc_macro(cx, ty)
|
&& !is_from_proc_macro(cx, ty)
|
||||||
{
|
{
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
|
|
|
@ -21,7 +21,6 @@ use rustc_hir::{
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
|
@ -164,7 +163,7 @@ fn check_fn_inner<'tcx>(
|
||||||
report_extra_lifetimes: bool,
|
report_extra_lifetimes: bool,
|
||||||
msrv: &Msrv,
|
msrv: &Msrv,
|
||||||
) {
|
) {
|
||||||
if in_external_macro(cx.sess(), span) || has_where_lifetimes(cx, generics) {
|
if span.in_external_macro(cx.sess().source_map()) || has_where_lifetimes(cx, generics) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_ast::ast::{Expr, ExprKind, LitKind};
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -207,7 +206,7 @@ impl_lint_pass!(LiteralDigitGrouping => [
|
||||||
impl EarlyLintPass for LiteralDigitGrouping {
|
impl EarlyLintPass for LiteralDigitGrouping {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||||
if let ExprKind::Lit(lit) = expr.kind
|
if let ExprKind::Lit(lit) = expr.kind
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
self.check_lit(cx, lit, expr.span);
|
self.check_lit(cx, lit, expr.span);
|
||||||
}
|
}
|
||||||
|
@ -421,7 +420,7 @@ impl_lint_pass!(DecimalLiteralRepresentation => [DECIMAL_LITERAL_REPRESENTATION]
|
||||||
impl EarlyLintPass for DecimalLiteralRepresentation {
|
impl EarlyLintPass for DecimalLiteralRepresentation {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||||
if let ExprKind::Lit(lit) = expr.kind
|
if let ExprKind::Lit(lit) = expr.kind
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
self.check_lit(cx, lit, expr.span);
|
self.check_lit(cx, lit, expr.span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_ast::Label;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
use super::INFINITE_LOOP;
|
use super::INFINITE_LOOP;
|
||||||
|
@ -30,7 +29,7 @@ pub(super) fn check<'tcx>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if in_external_macro(cx.sess(), expr.span) || is_from_proc_macro(cx, expr) {
|
if expr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, expr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
|
@ -142,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
||||||
// 16 possible alignments of constants/operands. For now, let's use `partition`.
|
// 16 possible alignments of constants/operands. For now, let's use `partition`.
|
||||||
&& let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
&& let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
||||||
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& (
|
&& (
|
||||||
is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
|
is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
|
||||||
|| self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
|
|| self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
|
use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
|
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::symbol::{Symbol, sym};
|
use rustc_span::symbol::{Symbol, sym};
|
||||||
|
@ -55,7 +54,7 @@ impl<'tcx> QuestionMark {
|
||||||
&& init.span.eq_ctxt(stmt.span)
|
&& init.span.eq_ctxt(stmt.span)
|
||||||
&& let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)
|
&& let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)
|
||||||
&& self.msrv.meets(msrvs::LET_ELSE)
|
&& self.msrv.meets(msrvs::LET_ELSE)
|
||||||
&& !in_external_macro(cx.sess(), stmt.span)
|
&& !stmt.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
match if_let_or_match {
|
match if_let_or_match {
|
||||||
IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => {
|
IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => {
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{PatExpr, PatExprKind, PatKind, RangeEnd};
|
use rustc_hir::{PatExpr, PatExprKind, PatKind, RangeEnd};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::{DUMMY_SP, Span};
|
use rustc_span::{DUMMY_SP, Span};
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ impl LateLintPass<'_> for ManualRangePatterns {
|
||||||
// like described https://github.com/rust-lang/rust-clippy/issues/11825)
|
// like described https://github.com/rust-lang/rust-clippy/issues/11825)
|
||||||
if let PatKind::Or(pats) = pat.kind
|
if let PatKind::Or(pats) = pat.kind
|
||||||
&& (pats.len() >= 3 || (pats.len() > 1 && pats.iter().any(|p| matches!(p.kind, PatKind::Range(..)))))
|
&& (pats.len() >= 3 || (pats.len() > 1 && pats.iter().any(|p| matches!(p.kind, PatKind::Range(..)))))
|
||||||
&& !in_external_macro(cx.sess(), pat.span)
|
&& !pat.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
let mut min = Num::dummy(i128::MAX);
|
let mut min = Num::dummy(i128::MAX);
|
||||||
let mut max = Num::dummy(i128::MIN);
|
let mut max = Num::dummy(i128::MIN);
|
||||||
|
|
|
@ -7,7 +7,6 @@ use clippy_utils::{is_in_const_context, path_to_local};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
|
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -60,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
|
||||||
&& rem_rhs.span.ctxt() == ctxt
|
&& rem_rhs.span.ctxt() == ctxt
|
||||||
&& add_lhs.span.ctxt() == ctxt
|
&& add_lhs.span.ctxt() == ctxt
|
||||||
&& add_rhs.span.ctxt() == ctxt
|
&& add_rhs.span.ctxt() == ctxt
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& self.msrv.meets(msrvs::REM_EUCLID)
|
&& self.msrv.meets(msrvs::REM_EUCLID)
|
||||||
&& (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx))
|
&& (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx))
|
||||||
&& let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs)
|
&& let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs)
|
||||||
|
|
|
@ -33,7 +33,6 @@ use clippy_utils::{
|
||||||
};
|
};
|
||||||
use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
|
use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::{SpanData, SyntaxContext};
|
use rustc_span::{SpanData, SyntaxContext};
|
||||||
|
|
||||||
|
@ -1054,7 +1053,7 @@ impl_lint_pass!(Matches => [
|
||||||
impl<'tcx> LateLintPass<'tcx> for Matches {
|
impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if is_direct_expn_of(expr.span, "matches").is_none() && in_external_macro(cx.sess(), expr.span) {
|
if is_direct_expn_of(expr.span, "matches").is_none() && expr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let from_expansion = expr.span.from_expansion();
|
let from_expansion = expr.span.from_expansion();
|
||||||
|
|
|
@ -11,7 +11,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::LangItem::OptionNone;
|
use rustc_hir::LangItem::OptionNone;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -188,7 +187,7 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
|
||||||
if is_non_aggregate_primitive_type(expr_type) {
|
if is_non_aggregate_primitive_type(expr_type) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_default_equivalent(cx, src) && !in_external_macro(cx.tcx.sess, expr_span) {
|
if is_default_equivalent(cx, src) && !expr_span.in_external_macro(cx.tcx.sess.source_map()) {
|
||||||
let Some(top_crate) = std_or_core(cx) else { return };
|
let Some(top_crate) = std_or_core(cx) else { return };
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -6,13 +6,12 @@ use clippy_utils::{is_from_proc_macro, is_trait_method, peel_blocks};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::Binder;
|
use rustc_middle::ty::Binder;
|
||||||
use rustc_middle::ty::adjustment::Adjust;
|
use rustc_middle::ty::adjustment::Adjust;
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
|
||||||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &Expr<'_>, call_span: Span) {
|
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &Expr<'_>, call_span: Span) {
|
||||||
if !in_external_macro(cx.sess(), expr.span)
|
if !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& is_trait_method(cx, expr, sym::Iterator)
|
&& is_trait_method(cx, expr, sym::Iterator)
|
||||||
&& let ExprKind::Closure(closure) = arg.kind
|
&& let ExprKind::Closure(closure) = arg.kind
|
||||||
&& let body = cx.tcx.hir().body(closure.body)
|
&& let body = cx.tcx.hir().body(closure.body)
|
||||||
|
|
|
@ -4,7 +4,6 @@ use clippy_utils::macros::{is_assert_macro, root_macro_call};
|
||||||
use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local};
|
use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local};
|
||||||
use rustc_hir::{Expr, HirId};
|
use rustc_hir::{Expr, HirId};
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
use super::CONST_IS_EMPTY;
|
use super::CONST_IS_EMPTY;
|
||||||
|
@ -12,7 +11,7 @@ use super::CONST_IS_EMPTY;
|
||||||
/// Expression whose initialization depend on a constant conditioned by a `#[cfg(…)]` directive will
|
/// Expression whose initialization depend on a constant conditioned by a `#[cfg(…)]` directive will
|
||||||
/// not trigger the lint.
|
/// not trigger the lint.
|
||||||
pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_>) {
|
pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_>) {
|
||||||
if in_external_macro(cx.sess(), expr.span) || !receiver.span.eq_ctxt(expr.span) {
|
if expr.span.in_external_macro(cx.sess().source_map()) || !receiver.span.eq_ctxt(expr.span) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(parent) = get_parent_expr(cx, expr) {
|
if let Some(parent) = get_parent_expr(cx, expr) {
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LintContext};
|
use rustc_lint::{LateContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
|
||||||
use super::MANUAL_TRY_FOLD;
|
use super::MANUAL_TRY_FOLD;
|
||||||
|
@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
|
||||||
fold_span: Span,
|
fold_span: Span,
|
||||||
msrv: &Msrv,
|
msrv: &Msrv,
|
||||||
) {
|
) {
|
||||||
if !in_external_macro(cx.sess(), fold_span)
|
if !fold_span.in_external_macro(cx.sess().source_map())
|
||||||
&& msrv.meets(msrvs::ITERATOR_TRY_FOLD)
|
&& msrv.meets(msrvs::ITERATOR_TRY_FOLD)
|
||||||
&& is_trait_method(cx, expr, sym::Iterator)
|
&& is_trait_method(cx, expr, sym::Iterator)
|
||||||
&& let init_ty = cx.typeck_results().expr_ty(init)
|
&& let init_ty = cx.typeck_results().expr_ty(init)
|
||||||
|
|
|
@ -152,7 +152,6 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
|
use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, TraitRef, Ty};
|
use rustc_middle::ty::{self, TraitRef, Ty};
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
@ -4625,7 +4624,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
||||||
if in_external_macro(cx.sess(), impl_item.span) {
|
if impl_item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let name = impl_item.ident.name.as_str();
|
let name = impl_item.ident.name.as_str();
|
||||||
|
@ -4713,7 +4712,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
|
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
|
||||||
if in_external_macro(cx.tcx.sess, item.span) {
|
if item.span.in_external_macro(cx.tcx.sess.source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};
|
use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};
|
||||||
use rustc_hir::{GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem, UsePath};
|
use rustc_hir::{GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem, UsePath};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -55,7 +54,7 @@ impl MinIdentChars {
|
||||||
|
|
||||||
#[expect(clippy::cast_possible_truncation)]
|
#[expect(clippy::cast_possible_truncation)]
|
||||||
fn is_ident_too_short(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {
|
fn is_ident_too_short(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {
|
||||||
!in_external_macro(cx.sess(), span)
|
!span.in_external_macro(cx.sess().source_map())
|
||||||
&& str.len() <= self.min_ident_chars_threshold as usize
|
&& str.len() <= self.min_ident_chars_threshold as usize
|
||||||
&& !str.starts_with('_')
|
&& !str.starts_with('_')
|
||||||
&& !str.is_empty()
|
&& !str.is_empty()
|
||||||
|
|
|
@ -13,7 +13,6 @@ use rustc_hir::{
|
||||||
BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
|
BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
|
@ -162,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
|
||||||
for arg in iter_input_pats(decl, body) {
|
for arg in iter_input_pats(decl, body) {
|
||||||
if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind
|
if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind
|
||||||
&& is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id)
|
&& is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id)
|
||||||
&& !in_external_macro(cx.tcx.sess, arg.span)
|
&& !arg.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
{
|
{
|
||||||
span_lint_hir(
|
span_lint_hir(
|
||||||
cx,
|
cx,
|
||||||
|
@ -183,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
|
||||||
&& let Some(init) = local.init
|
&& let Some(init) = local.init
|
||||||
// Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.
|
// Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.
|
||||||
&& is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id)
|
&& is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id)
|
||||||
&& !in_external_macro(cx.tcx.sess, stmt.span)
|
&& !stmt.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
{
|
{
|
||||||
let ctxt = local.span.ctxt();
|
let ctxt = local.span.ctxt();
|
||||||
let mut app = Applicability::MachineApplicable;
|
let mut app = Applicability::MachineApplicable;
|
||||||
|
@ -239,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if in_external_macro(cx.sess(), expr.span)
|
if expr.span.in_external_macro(cx.sess().source_map())
|
||||||
|| expr.span.desugaring_kind().is_some()
|
|| expr.span.desugaring_kind().is_some()
|
||||||
|| in_automatically_derived(cx.tcx, expr.hir_id)
|
|| in_automatically_derived(cx.tcx, expr.hir_id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,6 @@ use rustc_ast::token;
|
||||||
use rustc_ast::visit::FnKind;
|
use rustc_ast::visit::FnKind;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -350,7 +349,7 @@ impl EarlyLintPass for MiscEarlyLints {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {
|
fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {
|
||||||
if in_external_macro(cx.sess(), pat.span) {
|
if pat.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +386,7 @@ impl EarlyLintPass for MiscEarlyLints {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||||
if in_external_macro(cx.sess(), expr.span) {
|
if expr.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use rustc_ast::{Pat, PatKind};
|
use rustc_ast::{Pat, PatKind};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, LintContext};
|
use rustc_lint::{EarlyContext, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
|
|
||||||
use super::REDUNDANT_AT_REST_PATTERN;
|
use super::REDUNDANT_AT_REST_PATTERN;
|
||||||
|
|
||||||
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
|
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
|
||||||
if !in_external_macro(cx.sess(), pat.span)
|
if !pat.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let PatKind::Slice(slice) = &pat.kind
|
&& let PatKind::Slice(slice) = &pat.kind
|
||||||
&& let [one] = &**slice
|
&& let [one] = &**slice
|
||||||
&& let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind
|
&& let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind
|
||||||
|
|
|
@ -8,7 +8,6 @@ use rustc_hir::def_id::CRATE_DEF_ID;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
|
use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -106,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
|
if span.in_external_macro(cx.tcx.sess.source_map()) || is_entrypoint_fn(cx, def_id.to_def_id()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
|
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
|
||||||
if rustc_middle::lint::in_external_macro(cx.sess(), it.span) || is_executable_or_proc_macro(cx) {
|
if it.span.in_external_macro(cx.sess().source_map()) || is_executable_or_proc_macro(cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
||||||
if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable_or_proc_macro(cx) {
|
if impl_item.span.in_external_macro(cx.sess().source_map()) || is_executable_or_proc_macro(cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use hir::{BlockCheckMode, ExprKind, QPath, UnOp};
|
||||||
use rustc_ast::Mutability;
|
use rustc_ast::Mutability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::{DesugaringKind, Span};
|
use rustc_span::{DesugaringKind, Span};
|
||||||
|
@ -65,7 +64,7 @@ declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK])
|
||||||
impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
|
impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
|
||||||
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
|
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
|
||||||
if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_))
|
if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_))
|
||||||
|| in_external_macro(cx.tcx.sess, block.span)
|
|| block.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
|| block.span.is_desugaring(DesugaringKind::Await)
|
|| block.span.is_desugaring(DesugaringKind::Await)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2,7 +2,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_hir};
|
||||||
use clippy_utils::higher;
|
use clippy_utils::higher;
|
||||||
use rustc_hir::{self as hir, AmbigArg, intravisit};
|
use rustc_hir::{self as hir, AmbigArg, intravisit};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
|
||||||
&& mty.mutbl == hir::Mutability::Mut
|
&& mty.mutbl == hir::Mutability::Mut
|
||||||
&& let hir::TyKind::Ref(_, mty) = mty.ty.kind
|
&& let hir::TyKind::Ref(_, mty) = mty.ty.kind
|
||||||
&& mty.mutbl == hir::Mutability::Mut
|
&& mty.mutbl == hir::Mutability::Mut
|
||||||
&& !in_external_macro(cx.sess(), ty.span)
|
&& !ty.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
span_lint(
|
span_lint(
|
||||||
cx,
|
cx,
|
||||||
|
@ -56,7 +55,7 @@ pub struct MutVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
|
impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
|
||||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
|
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
|
||||||
if in_external_macro(self.cx.sess(), expr.span) {
|
if expr.span.in_external_macro(self.cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{ExprKind, Stmt, StmtKind};
|
use rustc_hir::{ExprKind, Stmt, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -47,7 +46,7 @@ impl LateLintPass<'_> for NeedlessIf {
|
||||||
&& let ExprKind::Block(block, ..) = then.kind
|
&& let ExprKind::Block(block, ..) = then.kind
|
||||||
&& block.stmts.is_empty()
|
&& block.stmts.is_empty()
|
||||||
&& block.expr.is_none()
|
&& block.expr.is_none()
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& then.span.check_source_text(cx, |src| {
|
&& then.span.check_source_text(cx, |src| {
|
||||||
// Ignore
|
// Ignore
|
||||||
// - empty macro expansions
|
// - empty macro expansions
|
||||||
|
|
|
@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
|
||||||
use clippy_utils::ty::implements_trait;
|
use clippy_utils::ty::implements_trait;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
|
@ -48,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
|
||||||
if let ExprKind::Unary(UnOp::Not, inner) = expr.kind
|
if let ExprKind::Unary(UnOp::Not, inner) = expr.kind
|
||||||
&& let ExprKind::Binary(ref op, left, _) = inner.kind
|
&& let ExprKind::Binary(ref op, left, _) = inner.kind
|
||||||
&& let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node
|
&& let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
let ty = cx.typeck_results().expr_ty(left);
|
let ty = cx.typeck_results().expr_ty(left);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::HirIdSet;
|
use rustc_hir::HirIdSet;
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
|
@ -69,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
||||||
for assoc_item in *items {
|
for assoc_item in *items {
|
||||||
if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
|
if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
|
||||||
let impl_item = cx.tcx.hir().impl_item(assoc_item.id);
|
let impl_item = cx.tcx.hir().impl_item(assoc_item.id);
|
||||||
if in_external_macro(cx.sess(), impl_item.span) {
|
if impl_item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
|
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
|
||||||
|
|
|
@ -12,7 +12,6 @@ use rustc_hir::{
|
||||||
};
|
};
|
||||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||||
|
@ -268,7 +267,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||||
|
|
||||||
fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
||||||
if let StmtKind::Semi(expr) = stmt.kind
|
if let StmtKind::Semi(expr) = stmt.kind
|
||||||
&& !in_external_macro(cx.sess(), stmt.span)
|
&& !stmt.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let ctxt = stmt.span.ctxt()
|
&& let ctxt = stmt.span.ctxt()
|
||||||
&& expr.span.ctxt() == ctxt
|
&& expr.span.ctxt() == ctxt
|
||||||
&& let Some(reduced) = reduce_expression(cx, expr)
|
&& let Some(reduced) = reduce_expression(cx, expr)
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
|
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::EarlyBinder;
|
use rustc_middle::ty::EarlyBinder;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
@ -129,7 +128,7 @@ impl LateLintPass<'_> for NonCanonicalImpls {
|
||||||
let ExprKind::Block(block, ..) = body.value.kind else {
|
let ExprKind::Block(block, ..) = body.value.kind else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if in_external_macro(cx.sess(), block.span) || is_from_proc_macro(cx, impl_item) {
|
if block.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, impl_item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_ast::ast::{
|
||||||
};
|
};
|
||||||
use rustc_ast::visit::{Visitor, walk_block, walk_expr, walk_pat};
|
use rustc_ast::visit::{Visitor, walk_block, walk_expr, walk_pat};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::symbol::{Ident, Symbol};
|
use rustc_span::symbol::{Ident, Symbol};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
|
@ -381,7 +380,7 @@ impl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {
|
||||||
|
|
||||||
impl EarlyLintPass for NonExpressiveNames {
|
impl EarlyLintPass for NonExpressiveNames {
|
||||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||||
if in_external_macro(cx.sess(), item.span) {
|
if item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +395,7 @@ impl EarlyLintPass for NonExpressiveNames {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
|
fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
|
||||||
if in_external_macro(cx.sess(), item.span) {
|
if item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_ast::ImplPolarity;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{FieldDef, Item, ItemKind, Node};
|
use rustc_hir::{FieldDef, Item, ItemKind, Node};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty::{self, GenericArgKind, Ty};
|
use rustc_middle::ty::{self, GenericArgKind, Ty};
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
@ -81,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
|
||||||
// We start from `Send` impl instead of `check_field_def()` because
|
// We start from `Send` impl instead of `check_field_def()` because
|
||||||
// single `AdtDef` may have multiple `Send` impls due to generic
|
// single `AdtDef` may have multiple `Send` impls due to generic
|
||||||
// parameters, and the lint is much easier to implement in this way.
|
// parameters, and the lint is much easier to implement in this way.
|
||||||
if !in_external_macro(cx.tcx.sess, item.span)
|
if !item.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
&& let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
|
&& let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
|
||||||
&& let ItemKind::Impl(hir_impl) = &item.kind
|
&& let ItemKind::Impl(hir_impl) = &item.kind
|
||||||
&& let Some(trait_ref) = &hir_impl.of_trait
|
&& let Some(trait_ref) = &hir_impl.of_trait
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId};
|
use rustc_hir::def_id::{CrateNum, DefId};
|
||||||
use rustc_hir::{self as hir, BodyId, Expr, ExprKind, Item, ItemKind};
|
use rustc_hir::{self as hir, BodyId, Expr, ExprKind, Item, ItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -139,7 +138,7 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if in_external_macro(cx.sess(), item.span) {
|
if item.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ use rustc_ast::token::LitKind;
|
||||||
use rustc_ast::{Expr, ExprKind};
|
use rustc_ast::{Expr, ExprKind};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::{BytePos, Pos, SpanData};
|
use rustc_span::{BytePos, Pos, SpanData};
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ impl EarlyLintPass for OctalEscapes {
|
||||||
LitKind::ByteStr | LitKind::CStr => 2,
|
LitKind::ByteStr | LitKind::CStr => 2,
|
||||||
_ => return,
|
_ => return,
|
||||||
})
|
})
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
{
|
{
|
||||||
let s = lit.symbol.as_str();
|
let s = lit.symbol.as_str();
|
||||||
let mut iter = s.as_bytes().iter();
|
let mut iter = s.as_bytes().iter();
|
||||||
|
|
|
@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
|
||||||
use clippy_utils::eq_expr_value;
|
use clippy_utils::eq_expr_value;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PanickingOverflowChecks {
|
||||||
&& matches!(ty.kind(), ty::Uint(_))
|
&& matches!(ty.kind(), ty::Uint(_))
|
||||||
&& ty == typeck.expr_ty(op_rhs)
|
&& ty == typeck.expr_ty(op_rhs)
|
||||||
&& ty == typeck.expr_ty(other)
|
&& ty == typeck.expr_ty(other)
|
||||||
&& !in_external_macro(cx.tcx.sess, expr.span)
|
&& !expr.span.in_external_macro(cx.tcx.sess.source_map())
|
||||||
&& (eq_expr_value(cx, op_lhs, other) || (commutative && eq_expr_value(cx, op_rhs, other)))
|
&& (eq_expr_value(cx, op_lhs, other) || (commutative && eq_expr_value(cx, op_rhs, other)))
|
||||||
{
|
{
|
||||||
span_lint(
|
span_lint(
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind, TyKind};
|
use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::{Span, Symbol, sym};
|
use rustc_span::{Span, Symbol, sym};
|
||||||
|
|
||||||
|
@ -136,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {
|
||||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
|
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
|
||||||
if let Some(init_expr) = local.init
|
if let Some(init_expr) = local.init
|
||||||
&& let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind
|
&& let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind
|
||||||
&& !in_external_macro(cx.sess(), local.span)
|
&& !local.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let ty = cx.typeck_results().pat_ty(local.pat)
|
&& let ty = cx.typeck_results().pat_ty(local.pat)
|
||||||
&& is_type_diagnostic_item(cx, ty, sym::PathBuf)
|
&& is_type_diagnostic_item(cx, ty, sym::PathBuf)
|
||||||
{
|
{
|
||||||
|
@ -157,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {
|
||||||
&& let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
|
&& let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
|
||||||
&& let [name] = &path.segments
|
&& let [name] = &path.segments
|
||||||
&& let Res::Local(id) = path.res
|
&& let Res::Local(id) = path.res
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& let ty = cx.typeck_results().expr_ty(left)
|
&& let ty = cx.typeck_results().expr_ty(left)
|
||||||
&& is_type_diagnostic_item(cx, ty, sym::PathBuf)
|
&& is_type_diagnostic_item(cx, ty, sym::PathBuf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,6 @@ use rustc_hir::{
|
||||||
Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind, intravisit,
|
Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind, intravisit,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -84,7 +83,7 @@ declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);
|
||||||
impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
|
impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
|
||||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
|
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
|
||||||
if let StmtKind::Let(local) = stmt.kind {
|
if let StmtKind::Let(local) = stmt.kind {
|
||||||
if in_external_macro(cx.sess(), local.pat.span) {
|
if local.pat.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let deref_possible = match local.source {
|
let deref_possible = match local.source {
|
||||||
|
@ -171,7 +170,7 @@ fn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mut
|
||||||
if result.is_some() {
|
if result.is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if in_external_macro(cx.sess(), p.span) {
|
if p.span.in_external_macro(cx.sess().source_map()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let adjust_pat = match p.kind {
|
let adjust_pat = match p.kind {
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_ast::ast::{Expr, ExprKind};
|
||||||
use rustc_ast::token::LitKind;
|
use rustc_ast::token::LitKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::{BytePos, Pos, Span};
|
use rustc_span::{BytePos, Pos, Span};
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
@ -72,7 +71,7 @@ impl RawStrings {
|
||||||
impl EarlyLintPass for RawStrings {
|
impl EarlyLintPass for RawStrings {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||||
if let ExprKind::FormatArgs(format_args) = &expr.kind
|
if let ExprKind::FormatArgs(format_args) = &expr.kind
|
||||||
&& !in_external_macro(cx.sess(), format_args.span)
|
&& !format_args.span.in_external_macro(cx.sess().source_map())
|
||||||
&& format_args.span.check_source_text(cx, |src| src.starts_with('r'))
|
&& format_args.span.check_source_text(cx, |src| src.starts_with('r'))
|
||||||
&& let Some(str) = snippet_opt(cx.sess(), format_args.span)
|
&& let Some(str) = snippet_opt(cx.sess(), format_args.span)
|
||||||
&& let count_hash = str.bytes().skip(1).take_while(|b| *b == b'#').count()
|
&& let count_hash = str.bytes().skip(1).take_while(|b| *b == b'#').count()
|
||||||
|
@ -95,7 +94,7 @@ impl EarlyLintPass for RawStrings {
|
||||||
LitKind::CStrRaw(max) => ("cr", max),
|
LitKind::CStrRaw(max) => ("cr", max),
|
||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||||
&& expr.span.check_source_text(cx, |src| src.starts_with(prefix))
|
&& expr.span.check_source_text(cx, |src| src.starts_with(prefix))
|
||||||
{
|
{
|
||||||
self.check_raw_string(cx, lit.symbol.as_str(), expr.span, prefix, max, lit.kind.descr());
|
self.check_raw_string(cx, lit.symbol.as_str(), expr.span, prefix, max, lit.kind.descr());
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue