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:
bors 2025-02-02 19:13:36 +00:00
commit 4a43094662
143 changed files with 774 additions and 1179 deletions

View File

@ -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.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic)]
@ -147,8 +137,9 @@ pub enum StabilityLevel {
Stable {
/// Rust release which stabilized this feature.
since: StableSince,
/// This is `Some` if this item allowed to be referred to on stable via unstable modules.
allowed_through_unstable_modules: Option<AllowedThroughUnstableModules>,
/// This is `Some` if this item allowed to be referred to on stable via unstable modules;
/// the `Symbol` is the deprecation message printed in that case.
allowed_through_unstable_modules: Option<Symbol>,
},
}

View File

@ -6,12 +6,12 @@ use rustc_ast::MetaItem;
use rustc_ast::attr::AttributeExt;
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::{
AllowedThroughUnstableModules, ConstStability, DefaultBodyStability, Stability, StabilityLevel,
StableSince, UnstableReason, VERSION_PLACEHOLDER,
ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, UnstableReason,
VERSION_PLACEHOLDER,
};
use rustc_errors::ErrorGuaranteed;
use rustc_session::Session;
use rustc_span::{Span, Symbol, sym};
use rustc_span::{Span, Symbol, kw, sym};
use crate::attributes::util::UnsupportedLiteralReason;
use crate::{parse_version, session_diagnostics};
@ -29,10 +29,14 @@ pub fn find_stability(
for attr in attrs {
match attr.name_or_empty() {
sym::rustc_allowed_through_unstable_modules => {
allowed_through_unstable_modules = Some(match attr.value_str() {
Some(msg) => AllowedThroughUnstableModules::WithDeprecation(msg),
None => AllowedThroughUnstableModules::WithoutDeprecation,
})
// The value is mandatory, but avoid ICEs in case such code reaches this function.
allowed_through_unstable_modules = Some(attr.value_str().unwrap_or_else(|| {
sess.dcx().span_delayed_bug(
item_sp,
"`#[rustc_allowed_through_unstable_modules]` without deprecation message",
);
kw::Empty
}))
}
sym::unstable => {
if stab.is_some() {

View File

@ -248,7 +248,98 @@ impl<'tcx> BorrowExplanation<'tcx> {
);
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 {
// #85581: If the first mutable borrow's scope contains
// the second borrow, this suggestion isn't helpful.
@ -281,23 +372,6 @@ impl<'tcx> BorrowExplanation<'tcx> {
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);
}
}
}

View File

@ -56,7 +56,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
let (ident, vdata, fields) = match substr.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),
EnumDiscr(..) | StaticStruct(..) | StaticEnum(..) => {
cx.dcx().span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")

View File

@ -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)
}
}
}

View File

@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_default(
StaticStruct(_, 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())
}
_ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"),

View File

@ -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)"),
}
}

View File

@ -311,7 +311,7 @@ pub(crate) enum SubstructureFields<'a> {
/// Matching variants of the enum: variant index, ast::Variant,
/// fields: the field name is only non-`None` in the case of a struct
/// 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
/// 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),
/// 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
@ -1270,7 +1270,7 @@ impl<'a> MethodDef<'a> {
trait_,
type_ident,
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()
let mut match_arms: ThinVec<ast::Arm> = variants
.iter()
.enumerate()
.filter(|&(_, v)| !(unify_fieldless_variants && v.data.fields().is_empty()))
.map(|(index, variant)| {
.filter(|&v| !(unify_fieldless_variants && v.data.fields().is_empty()))
.map(|variant| {
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
// (see "Final wrinkle" note below for why.)
@ -1316,7 +1315,7 @@ impl<'a> MethodDef<'a> {
// expressions for referencing every field of every
// Self arg, assuming all are instances of VariantK.
// Build up code associated with such a case.
let substructure = EnumMatching(index, variant, fields);
let substructure = EnumMatching(variant, fields);
let arm_expr = self
.call_substructure_method(
cx,
@ -1344,7 +1343,7 @@ impl<'a> MethodDef<'a> {
trait_,
type_ident,
nonselflike_args,
&EnumMatching(0, v, Vec::new()),
&EnumMatching(v, Vec::new()),
)
.into_expr(cx, span),
)
@ -1407,21 +1406,12 @@ impl<'a> MethodDef<'a> {
type_ident: Ident,
nonselflike_args: &[P<Expr>],
) -> 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(
cx,
trait_,
type_ident,
nonselflike_args,
&StaticEnum(enum_def, summary),
&StaticEnum(enum_def),
)
}
}

View File

@ -21,7 +21,6 @@ pub(crate) struct Path {
#[derive(Clone)]
pub(crate) enum PathKind {
Local,
Global,
Std,
}
@ -57,7 +56,6 @@ impl Path {
let params = tys.map(GenericArg::Type).collect();
match self.kind {
PathKind::Global => cx.path_all(span, true, idents, params),
PathKind::Local => cx.path_all(span, false, idents, params),
PathKind::Std => {
let def_site = cx.with_def_site_ctxt(DUMMY_SP);

View File

@ -23,9 +23,7 @@ pub(crate) mod bounds;
pub(crate) mod clone;
pub(crate) mod coerce_pointee;
pub(crate) mod debug;
pub(crate) mod decodable;
pub(crate) mod default;
pub(crate) mod encodable;
pub(crate) mod hash;
#[path = "cmp/eq.rs"]

View File

@ -132,8 +132,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
Ord: ord::expand_deriving_ord,
PartialEq: partial_eq::expand_deriving_partial_eq,
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,
}

View File

@ -644,7 +644,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
found_label: &dyn fmt::Display,
found: DiagStyledString,
) -> &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]
@ -654,8 +661,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
expected: DiagStyledString,
found_label: &dyn fmt::Display,
found: DiagStyledString,
expected_extra: &dyn fmt::Display,
found_extra: &dyn fmt::Display,
expected_extra: DiagStyledString,
found_extra: DiagStyledString,
) -> &mut Self {
let expected_label = expected_label.to_string();
let expected_label = if expected_label.is_empty() {
@ -680,10 +687,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
expected_label
))];
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.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.
self.highlighted_note(msg);

View File

@ -616,7 +616,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
),
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,
"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
through unstable paths"

View File

@ -50,7 +50,6 @@ use rustc_infer::traits::{
IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation,
PredicateObligations,
};
use rustc_middle::lint::in_external_macro;
use rustc_middle::span_bug;
use rustc_middle::traits::BuiltinImplSource;
use rustc_middle::ty::adjustment::{
@ -1937,7 +1936,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
cond_expr.span.desugaring_kind(),
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!(
cond_expr.kind,
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))

View File

@ -14,7 +14,6 @@ use rustc_hir::{
};
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
use rustc_hir_analysis::suggest_impl_trait;
use rustc_middle::lint::in_external_macro;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::span_bug;
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
// adding a semicolon, because there's nowhere to put it.
// See issue #81943.
&& !in_external_macro(self.tcx.sess, expression.span) =>
&& !expression.span.in_external_macro(self.tcx.sess.source_map()) =>
{
if needs_block {
err.multipart_suggestion(
@ -2261,7 +2260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
expr_ty: Ty<'tcx>,
) -> bool {
if in_external_macro(self.tcx.sess, expr.span) {
if expr.span.in_external_macro(self.tcx.sess.source_map()) {
return false;
}
if let ty::Adt(expected_adt, args) = expected.kind() {
@ -2589,14 +2588,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)> {
let sess = self.sess();
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 in_external_macro(sess, sp) {
if sp.in_external_macro(sm) {
return None;
}
let sm = sess.source_map();
let replace_prefix = |s: &str, old: &str, new: &str| {
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
};

View File

@ -29,7 +29,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::FnKind as HirFnKind;
use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
use rustc_middle::bug;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
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)?;
if in_external_macro(tcx.sess, span) {
if span.in_external_macro(tcx.sess.source_map()) {
return None;
}

View File

@ -135,7 +135,7 @@ pub(super) fn unexpected_cfg_name(
};
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 code_sugg = if is_feature_cfg && is_from_cargo {
@ -281,7 +281,7 @@ pub(super) fn unexpected_cfg_value(
.collect();
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
// for names as the possibilities could be very long

View File

@ -2,7 +2,6 @@ use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::lint::in_external_macro;
use rustc_middle::{bug, ty};
use rustc_parse_format::{ParseMode, Parser, Piece};
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);
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.
return;
}
@ -229,14 +228,15 @@ fn check_panic_str<'tcx>(
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.
return;
}
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) => {
// Count the number of `#`s between the `r` and `"`.
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 `)`,
/// and the type of (opening) delimiter used.
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 close = snippet.rfind(|c| ")]}".contains(c))?;
Some((

View File

@ -8,8 +8,7 @@ use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_session::Session;
use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::{DUMMY_SP, DesugaringKind, Span, Symbol, kw};
use rustc_span::{DUMMY_SP, Span, Symbol, kw};
use tracing::instrument;
use crate::ty::TyCtxt;
@ -201,7 +200,7 @@ impl LintExpectation {
}
}
pub fn explain_lint_level_source(
fn explain_lint_level_source(
lint: &'static Lint,
level: Level,
src: LintLevelSource,
@ -325,7 +324,7 @@ pub fn lint_level(
// 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
// 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
// emit shouldn't be automatically fixed by rustfix.
err.disable_suggestions();
@ -422,36 +421,3 @@ pub fn lint_level(
}
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,
}
}

View File

@ -92,51 +92,88 @@ impl<'tcx> MonoItem<'tcx> {
}
pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
let generate_cgu_internal_copies =
(tcx.sess.opts.optimize != OptLevel::No) && !tcx.sess.link_dead_code();
// The case handling here is written in the same style as cross_crate_inlinable, we first
// handle the cases where we must use a particular instantiation mode, then cascade down
// through a sequence of heuristics.
match *self {
MonoItem::Fn(ref instance) => {
let entry_def_id = tcx.entry_fn(()).map(|(id, _)| id);
// If this function isn't inlined or otherwise has an extern
// indicator, then we'll be creating a globally shared version.
let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
if codegen_fn_attrs.contains_extern_indicator()
|| 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 };
}
// The first thing we do is detect MonoItems which we must instantiate exactly once in the
// whole program.
if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
&& self.is_generic_fn()
{
// Upgrade inline(never) to a globally shared instance.
return InstantiationMode::GloballyShared { may_conflict: true };
}
// At this point we don't have explicit linkage and we're an
// inlined function. If this crate's build settings permit,
// we'll be creating a local copy per CGU.
if generate_cgu_internal_copies {
return InstantiationMode::LocalCopy;
}
// Finally, if this is `#[inline(always)]` we're sure to respect
// that with an inline copy per CGU, but otherwise we'll be
// creating one copy of this `#[inline]` function which may
// conflict with upstream crates as it could be an exported
// symbol.
if tcx.codegen_fn_attrs(instance.def_id()).inline.always() {
InstantiationMode::LocalCopy
} else {
InstantiationMode::GloballyShared { may_conflict: true }
}
}
// Statics and global_asm! must be instantiated exactly once.
let instance = match *self {
MonoItem::Fn(instance) => instance,
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
InstantiationMode::GloballyShared { may_conflict: false }
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());
if codegen_fn_attrs.contains_extern_indicator()
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
{
return InstantiationMode::GloballyShared { may_conflict: false };
}
// FIXME: The logic for which functions are permitted to get LocalCopy is actually spread
// across 4 functions:
// * cross_crate_inlinable(def_id)
// * 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 };
}
// To ensure that #[inline(always)] can be inlined as much as possible, especially in unoptimized
// builds, we always select LocalCopy.
if codegen_fn_attrs.inline.always() {
return InstantiationMode::LocalCopy;
}
// #[inline(never)] functions in general are poor candidates for inlining and thus since
// LocalCopy generally increases code size for the benefit of optimizations from inlining,
// we want to give them GloballyShared codegen.
// The slight problem is that generic functions need to always support cross-crate
// compilation, so all previous stages of the compiler are obligated to treat generic
// functions the same as those that unconditionally get LocalCopy codegen. It's only when
// we get here that we can at least not codegen a #[inline(never)] generic function in all
// of our CGUs.
if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
&& self.is_generic_fn()
{
return InstantiationMode::GloballyShared { may_conflict: true };
}
// 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,
}
}

View File

@ -5,8 +5,8 @@ use std::mem::replace;
use std::num::NonZero;
use rustc_attr_parsing::{
self as attr, AllowedThroughUnstableModules, ConstStability, DeprecatedSince, Stability,
StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER,
self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
UnstableReason, VERSION_PLACEHOLDER,
};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
@ -880,7 +880,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
if item_is_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 {
StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
allowed_through_unstable_modules
@ -888,84 +888,80 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
_ => None,
});
if is_allowed_through_unstable_modules.is_none() {
// 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
// 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.
//
// We check here rather than in `visit_path_segment` to prevent visiting the last
// path segment twice
//
// We include special cases via #[rustc_allowed_through_unstable_modules] for items
// that were accidentally stabilized through unstable paths before this check was
// added, such as `core::intrinsics::transmute`
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
self.tcx.check_stability_allow_unstable(
def_id,
None,
path.span,
None,
if is_unstable_reexport(self.tcx, id) {
AllowUnstable::Yes
} else {
AllowUnstable::No
},
);
}
}
} else if let Some(AllowedThroughUnstableModules::WithDeprecation(deprecation)) =
is_allowed_through_unstable_modules
{
// 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(
def_id,
None,
path.span,
None,
if is_unstable_reexport(self.tcx, id) {
AllowUnstable::Yes
} else {
AllowUnstable::No
},
);
let is_allowed = matches!(eval_result, EvalResult::Allow);
if !is_allowed {
// Calculating message for lint involves calling `self.def_path_str`,
// which will by default invoke the expensive `visible_parent_map` query.
// Skip all that work if the lint is allowed anyway.
if self.tcx.lint_level_at_node(DEPRECATED, id).0
== lint::Level::Allow
{
return;
}
// Show a deprecation message.
let def_path =
with_no_trimmed_paths!(self.tcx.def_path_str(def_id));
let def_kind = self.tcx.def_descr(def_id);
let diag = Deprecated {
sub: None,
kind: def_kind.to_owned(),
path: def_path,
note: Some(deprecation),
since_kind: lint::DeprecatedSinceKind::InEffect,
};
self.tcx.emit_node_span_lint(
DEPRECATED,
id,
method_span.unwrap_or(path.span),
diag,
// Check parent modules stability as well if the item the path refers to is itself
// 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
// both the segments and the item are unstable behind the same feature flag.
//
// We check here rather than in `visit_path_segment` to prevent visiting the last
// path segment twice
//
// We include special cases via #[rustc_allowed_through_unstable_modules] for items
// that were accidentally stabilized through unstable paths before this check was
// added, such as `core::intrinsics::transmute`
let parents = path.segments.iter().rev().skip(1);
for path_segment in parents {
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
self.tcx.check_stability_allow_unstable(
def_id,
None,
path.span,
None,
if is_unstable_reexport(self.tcx, id) {
AllowUnstable::Yes
} else {
AllowUnstable::No
},
);
}
Some(deprecation) => {
// Call the stability check directly so that we can control which
// diagnostic is emitted.
let eval_result = self.tcx.eval_stability_allow_unstable(
def_id,
None,
path.span,
None,
if is_unstable_reexport(self.tcx, id) {
AllowUnstable::Yes
} else {
AllowUnstable::No
},
);
let is_allowed = matches!(eval_result, EvalResult::Allow);
if !is_allowed {
// Calculating message for lint involves calling `self.def_path_str`,
// which will by default invoke the expensive `visible_parent_map` query.
// Skip all that work if the lint is allowed anyway.
if self.tcx.lint_level_at_node(DEPRECATED, id).0
== lint::Level::Allow
{
return;
}
// Show a deprecation message.
let def_path =
with_no_trimmed_paths!(self.tcx.def_path_str(def_id));
let def_kind = self.tcx.def_descr(def_id);
let diag = Deprecated {
sub: None,
kind: def_kind.to_owned(),
path: def_path,
note: Some(deprecation),
since_kind: lint::DeprecatedSinceKind::InEffect,
};
self.tcx.emit_node_span_lint(
DEPRECATED,
id,
method_span.unwrap_or(path.span),
diag,
);
}
}
}
}
}

View File

@ -600,11 +600,43 @@ impl Span {
!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.
pub fn in_derive_expansion(self) -> bool {
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.
pub fn can_be_used_for_suggestions(self) -> bool {
!self.from_expansion()

View File

@ -314,8 +314,6 @@ symbols! {
Right,
Rust,
RustaceansAreAwesome,
RustcDecodable,
RustcEncodable,
RwLock,
RwLockReadGuard,
RwLockWriteGuard,

View File

@ -1722,32 +1722,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}
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()) {
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
format!(
DiagStyledString::normal(format!(
" (opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
))
}
(true, ty::Alias(ty::Projection, proj))
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
{
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
format!(
DiagStyledString::normal(format!(
" (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
))
}
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
(true, _) => {
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())
|| (exp_found.is_some_and(|ef| {
@ -1764,23 +1774,23 @@ 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
// will try to hide in some case such as `async fn`, so
// to make an error more use friendly we will
// avoid to suggest a mismatch type with a
// type that the user usually are not using
// directly such as `impl Future<Output = u8>`.
if !self.tcx.ty_is_opaque_future(found_ty) {
diag.note_expected_found_extra(
&expected_label,
expected,
&found_label,
found,
&sort_string(values.expected),
&sort_string(values.found),
);
}
diag.note_expected_found_extra(
&expected_label,
expected,
&found_label,
found,
sort_string(values.expected),
sort_string(values.found),
);
}
}
}

View File

@ -712,8 +712,8 @@ impl String {
}
}
/// Decode a UTF-16encoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
/// Decode a native endian UTF-16encoded vector `v` into a `String`,
/// returning [`Err`] if `v` contains any invalid data.
///
/// # Examples
///
@ -745,8 +745,8 @@ impl String {
Ok(ret)
}
/// Decode a UTF-16encoded slice `v` into a `String`, replacing
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
/// Decode a native endian UTF-16encoded slice `v` into a `String`,
/// replacing invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
///
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
/// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8
@ -777,8 +777,8 @@ impl String {
.collect()
}
/// Decode a UTF-16LEencoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
/// Decode a UTF-16LEencoded vector `v` into a `String`,
/// returning [`Err`] if `v` contains any invalid data.
///
/// # Examples
///
@ -852,8 +852,8 @@ impl String {
}
}
/// Decode a UTF-16BEencoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
/// Decode a UTF-16BEencoded vector `v` into a `String`,
/// returning [`Err`] if `v` contains any invalid data.
///
/// # Examples
///

View File

@ -92,7 +92,7 @@ impl char {
#[stable(feature = "assoc_char_consts", since = "1.52.0")]
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.
///
/// # Examples
@ -704,7 +704,7 @@ impl char {
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.
///
/// # 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) }
}
/// 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.
///
/// Unlike `char::encode_utf16`, this method also handles codepoints in the surrogate range.

View File

@ -78,7 +78,11 @@ pub mod simd;
use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
#[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")]
#[inline]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {

View File

@ -1831,32 +1831,4 @@ pub(crate) mod builtin {
pub macro deref($pat: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 */
}
}

View File

@ -18,16 +18,6 @@ mod common;
pub mod v1 {
#[stable(feature = "rust1", since = "1.0.0")]
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.

View File

@ -1108,7 +1108,8 @@ impl str {
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
///

View File

@ -120,16 +120,6 @@ mod common;
pub mod v1 {
#[stable(feature = "rust1", since = "1.0.0")]
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.

View File

@ -5,9 +5,7 @@ use std::{fmt, iter};
use arrayvec::ArrayVec;
use rustc_abi::{ExternAbi, VariantIdx};
use rustc_attr_parsing::{
AllowedThroughUnstableModules, ConstStability, Deprecation, Stability, StableSince,
};
use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
@ -411,15 +409,9 @@ impl Item {
..
} = 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 {
since: rustc_attr_parsing::DeprecatedSince::Unspecified,
note,
note: Some(note),
suggestion: None,
})
} else {

View File

@ -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
[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
[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
[applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/

View File

@ -218,7 +218,7 @@ functions to deal with macros:
> 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
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.
@ -227,15 +227,13 @@ functions to deal with macros:
crates
```rust
use rustc_middle::lint::in_external_macro;
use a_crate_with_macros::foo;
// `foo` is defined in `a_crate_with_macros`
foo!("bar");
// 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

View File

@ -120,7 +120,7 @@ assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());
### 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.
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`):
```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.
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
[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
[`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
[SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html

View File

@ -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_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
declare_clippy_lint! {
@ -45,7 +44,7 @@ impl EarlyLintPass for AlmostCompleteRange {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
&& 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(
cx,
@ -74,7 +73,7 @@ impl EarlyLintPass for AlmostCompleteRange {
if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
&& matches!(kind.node, RangeEnd::Excluded)
&& 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(
cx,

View File

@ -9,7 +9,6 @@ use rustc_hir::{
Variant, VariantData,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
declare_clippy_lint! {
@ -248,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
let mut cur_v: Option<&Variant<'_>> = None;
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;
}
@ -263,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
let mut cur_f: Option<&FieldDef<'_>> = None;
for field in *fields {
if in_external_macro(cx.sess(), field.span) {
if field.span.in_external_macro(cx.sess().source_map()) {
continue;
}
@ -281,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
let mut cur_t: Option<&TraitItemRef> = None;
for item in *item_ref {
if in_external_macro(cx.sess(), item.span) {
if item.span.in_external_macro(cx.sess().source_map()) {
continue;
}
@ -304,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
let mut cur_t: Option<&ImplItemRef> = None;
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;
}
@ -348,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
// as no sorting by source map/line of code has to be applied.
//
for item in items {
if in_external_macro(cx.sess(), item.span) {
if item.span.in_external_macro(cx.sess().source_map()) {
continue;
}

View File

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -49,7 +48,7 @@ declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
impl<'tcx> LateLintPass<'tcx> for AsConversions {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
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)
{
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]

View File

@ -4,11 +4,10 @@ use clippy_utils::is_from_proc_macro;
use rustc_ast::{AttrStyle, Attribute};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
// Separate each crate's features.
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 Some(ident) = attr.ident()
&& !is_from_proc_macro(cx, attr)

View File

@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use rustc_ast::{MetaItemInner, MetaItemKind};
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::sym;
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
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;
}

View File

@ -5,14 +5,13 @@ use clippy_utils::source::{SpanRangeExt, first_line_of_span};
use rustc_ast::{Attribute, Item, ItemKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
for attr in attrs {
if in_external_macro(cx.sess(), attr.span) {
if attr.span.in_external_macro(cx.sess().source_map()) {
return;
}
if let Some(lint_list) = &attr.meta_item_list() {

View File

@ -4,7 +4,6 @@ use clippy_utils::{higher, is_from_proc_macro};
use rustc_errors::Applicability;
use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -54,7 +53,7 @@ const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression conditio
impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
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;
}

View File

@ -7,7 +7,6 @@ use rustc_hir::def::Res;
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LetStmt, Node, QPath, Ty, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
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())`
&& let ExprKind::Call(arg_path, _) = arg.kind
// 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
// or that we are inside a `vec!` macro expansion
&& (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))

View File

@ -29,7 +29,6 @@ use clippy_utils::is_hir_ty_cfg_dependant;
use clippy_utils::msrvs::{self, Msrv};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
declare_clippy_lint! {
@ -796,7 +795,7 @@ impl_lint_pass!(Casts => [
impl<'tcx> LateLintPass<'tcx> for Casts {
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;
}

View File

@ -8,7 +8,6 @@ use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
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)
&& !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
{

View File

@ -6,7 +6,6 @@ use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal};
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
declare_clippy_lint! {
@ -64,7 +63,7 @@ impl LateLintPass<'_> for CheckedConversions {
},
_ => return,
}
&& !in_external_macro(cx.sess(), item.span)
&& !item.span.in_external_macro(cx.sess().source_map())
&& !is_in_const_context(cx)
&& self.msrv.meets(msrvs::TRY_FROM)
&& let Some(cv) = match op2 {

View File

@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Node};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::{Span, SyntaxContext, sym};
@ -60,7 +59,7 @@ impl LateLintPass<'_> for DbgMacro {
if cur_syntax_ctxt != self.prev_ctxt &&
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) &&
// 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))

View File

@ -9,7 +9,6 @@ use rustc_hir::{
StructTailExpr,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
use rustc_session::declare_lint_pass;
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.
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!(
lit.node,

View File

@ -22,7 +22,6 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_resolve::rustdoc::{
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 {
ItemKind::Fn { sig, body: body_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);
@ -711,7 +710,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
},
Node::TraitItem(trait_item) => {
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(
cx,
@ -726,7 +725,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
},
Node::ImplItem(impl_item) => {
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())
{
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(
attrs.iter().filter_map(|attr| {
if in_external_macro(cx.sess(), attr.span) {
if attr.span.in_external_macro(cx.sess().source_map()) {
None
} else {
Some((attr, None))

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_ast::ast::{Expr, ExprKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -50,7 +49,7 @@ impl EarlyLintPass for ElseIfWithoutElse {
fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {
if let ExprKind::If(_, _, Some(ref els)) = item.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")]
span_lint_and_then(

View File

@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_lint_allowed;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::Ty;
use rustc_session::declare_lint_pass;
use rustc_span::Symbol;
@ -119,7 +118,7 @@ impl LateLintPass<'_> for EndianBytes {
},
_ => 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)
&& ty.is_primitive_ty()
{

View File

@ -4,7 +4,6 @@ use clippy_utils::ty::implements_trait;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::Ty;
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>) {
if let ExprKind::Let(let_expr) = expr.kind
&& 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 pat_ty = cx.typeck_results().pat_ty(let_expr.pat);

View File

@ -5,7 +5,6 @@ use rustc_ast::node_id::NodeSet;
use rustc_ast::visit::{Visitor, walk_block, walk_item};
use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
@ -125,7 +124,7 @@ struct NestingVisitor<'conf, 'cx> {
impl NestingVisitor<'_, '_> {
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);
return true;

View File

@ -10,7 +10,6 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use rustc_span::def_id::{DefId, LocalDefId};
@ -261,7 +260,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
&& !generics.params.is_empty()
&& !is_empty_body(cx, body_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)
{
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()
&& !is_empty_body(cx, body_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)
{
let mut walker = TypeWalker::new(cx, item.generics);

View File

@ -3,7 +3,6 @@ use clippy_utils::is_span_if;
use clippy_utils::source::snippet_opt;
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_span::Span;
@ -202,7 +201,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
if let ExprKind::If(_, then, Some(else_)) = &expr.kind
&& (is_block(else_) || is_if(else_))
&& !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
&& expr.span.lo().0 != 0 && expr.span.hi().0 != 0

View File

@ -5,7 +5,6 @@ use rustc_hir::def_id::DefIdSet;
use rustc_hir::{self as hir, Attribute, QPath};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
use rustc_span::{Span, sym};
@ -107,7 +106,7 @@ fn check_needless_must_use(
attrs: &[Attribute],
sig: &FnSig<'_>,
) {
if in_external_macro(cx.sess(), item_span) {
if item_span.in_external_macro(cx.sess().source_map()) {
return;
}
if returns_unit(decl) {
@ -185,7 +184,7 @@ fn check_must_use_candidate<'tcx>(
) {
if has_mutable_arg(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)
|| !cx.effective_visibilities.is_exported(item_id.def_id)
|| is_must_use_ty(cx, return_ty(cx, item_id))

View File

@ -2,7 +2,6 @@ use clippy_utils::msrvs::{self, Msrv};
use rustc_errors::Diag;
use rustc_hir as hir;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
use rustc_span::{Span, sym};
@ -20,7 +19,7 @@ fn result_err_ty<'tcx>(
id: hir::def_id::LocalDefId,
item_span: Span,
) -> 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 ty = cx
.tcx

View File

@ -3,7 +3,6 @@ use clippy_utils::source::SpanRangeExt;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::Span;
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`.
// 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;
}

View File

@ -11,7 +11,6 @@ use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
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_else_clause(cx.tcx, expr)
&& !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)
&& !contains_return(then_block.stmts)
{

View File

@ -7,7 +7,6 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_span::def_id::LocalDefId;
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(_)))
|| !span.eq_ctxt(body.value.span)
|| in_external_macro(cx.sess(), span)
|| span.in_external_macro(cx.sess().source_map())
{
return;
}

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_hir;
use rustc_hir::{Block, ItemKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -70,7 +69,7 @@ impl LateLintPass<'_> for ItemsAfterStatements {
// Don't use `next` due to the complex filter chain.
.for_each(|item| {
// 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(
cx,
ITEMS_AFTER_STATEMENTS,

View File

@ -6,7 +6,6 @@ use rustc_ast::Mutability;
use rustc_errors::Applicability;
use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
use rustc_session::declare_lint_pass;
use rustc_span::sym;
@ -131,7 +130,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
&& trait_ref
.trait_def_id()
.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 expected_method_name = match mtbl {
Mutability::Mut => sym::iter_mut,
@ -193,7 +192,7 @@ impl {self_ty_without_ref} {{
_ => 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 FnRetTy::Return(ret) = sig.decl.output
&& is_nameable_in_impl_trait(ret)

View File

@ -5,7 +5,6 @@ use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
use rustc_session::impl_lint_pass;
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::Adt(adt, subst) = ty.kind()
&& 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);

View File

@ -7,7 +7,6 @@ use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::symbol::kw;
use rustc_span::{Symbol, sym};
@ -54,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
// so lint on the `use` statement directly.
if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
&& 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 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)
&& !in_external_macro(cx.sess(), expr.span)
&& !expr.span.in_external_macro(cx.sess().source_map())
&& !is_from_proc_macro(cx, expr)
{
span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {

View File

@ -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 rustc_hir::{LetStmt, LocalSource, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{GenericArgKind, IsSuggestable};
use rustc_session::declare_lint_pass;
use rustc_span::{BytePos, Span};
@ -141,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
if matches!(local.source, LocalSource::Normal)
&& let PatKind::Wild = local.pat.kind
&& 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 contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {

View File

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_from_proc_macro;
use rustc_hir::{LetStmt, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
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
&& let TyKind::Infer(()) = &ty.kind // that type is '_'
&& 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)
{
span_lint_and_help(

View File

@ -21,7 +21,6 @@ use rustc_hir::{
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map;
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_span::Span;
use rustc_span::def_id::LocalDefId;
@ -164,7 +163,7 @@ fn check_fn_inner<'tcx>(
report_extra_lifetimes: bool,
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;
}

View File

@ -6,7 +6,6 @@ use rustc_ast::ast::{Expr, ExprKind, LitKind};
use rustc_ast::token;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use std::iter;
@ -207,7 +206,7 @@ impl_lint_pass!(LiteralDigitGrouping => [
impl EarlyLintPass for LiteralDigitGrouping {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
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);
}
@ -421,7 +420,7 @@ impl_lint_pass!(DecimalLiteralRepresentation => [DECIMAL_LITERAL_REPRESENTATION]
impl EarlyLintPass for DecimalLiteralRepresentation {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
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);
}

View File

@ -6,7 +6,6 @@ use rustc_ast::Label;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::sym;
use super::INFINITE_LOOP;
@ -30,7 +29,7 @@ pub(super) fn check<'tcx>(
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;
}

View File

@ -9,7 +9,6 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::TyCtxt;
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`.
&& 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
&& !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())
|| self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)

View File

@ -9,7 +9,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, sym};
@ -55,7 +54,7 @@ impl<'tcx> QuestionMark {
&& init.span.eq_ctxt(stmt.span)
&& let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)
&& 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 {
IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => {

View File

@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::{PatExpr, PatExprKind, PatKind, RangeEnd};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
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)
if let PatKind::Or(pats) = pat.kind
&& (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 max = Num::dummy(i128::MIN);

View File

@ -7,7 +7,6 @@ use clippy_utils::{is_in_const_context, path_to_local};
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
declare_clippy_lint! {
@ -60,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
&& rem_rhs.span.ctxt() == ctxt
&& add_lhs.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_CONST) || !is_in_const_context(cx))
&& let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs)

View File

@ -33,7 +33,6 @@ use clippy_utils::{
};
use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::{SpanData, SyntaxContext};
@ -1054,7 +1053,7 @@ impl_lint_pass!(Matches => [
impl<'tcx> LateLintPass<'tcx> for Matches {
#[expect(clippy::too_many_lines)]
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;
}
let from_expansion = expr.span.from_expansion();

View File

@ -11,7 +11,6 @@ use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
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) {
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 };
span_lint_and_then(
cx,

View File

@ -6,13 +6,12 @@ use clippy_utils::{is_from_proc_macro, is_trait_method, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::Binder;
use rustc_middle::ty::adjustment::Adjust;
use rustc_span::{Span, sym};
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)
&& let ExprKind::Closure(closure) = arg.kind
&& let body = cx.tcx.hir().body(closure.body)

View File

@ -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 rustc_hir::{Expr, HirId};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::sym;
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
/// not trigger the lint.
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;
}
if let Some(parent) = get_parent_expr(cx, expr) {

View File

@ -7,7 +7,6 @@ use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_span::{Span, sym};
use super::MANUAL_TRY_FOLD;
@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
fold_span: Span,
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)
&& is_trait_method(cx, expr, sym::Iterator)
&& let init_ty = cx.typeck_results().expr_ty(init)

View File

@ -152,7 +152,6 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, TraitRef, Ty};
use rustc_session::impl_lint_pass;
use rustc_span::{Span, sym};
@ -4625,7 +4624,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
#[allow(clippy::too_many_lines)]
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;
}
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<'_>) {
if in_external_macro(cx.tcx.sess, item.span) {
if item.span.in_external_macro(cx.tcx.sess.source_map()) {
return;
}

View File

@ -6,7 +6,6 @@ use rustc_hir::def::{DefKind, Res};
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_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use std::borrow::Cow;
@ -55,7 +54,7 @@ impl MinIdentChars {
#[expect(clippy::cast_possible_truncation)]
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.starts_with('_')
&& !str.is_empty()

View File

@ -13,7 +13,6 @@ use rustc_hir::{
BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_span::Span;
use rustc_span::def_id::LocalDefId;
@ -162,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
for arg in iter_input_pats(decl, body) {
if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind
&& 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(
cx,
@ -183,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
&& let Some(init) = local.init
// 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)
&& !in_external_macro(cx.tcx.sess, stmt.span)
&& !stmt.span.in_external_macro(cx.tcx.sess.source_map())
{
let ctxt = local.span.ctxt();
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<'_>) {
if in_external_macro(cx.sess(), expr.span)
if expr.span.in_external_macro(cx.sess().source_map())
|| expr.span.desugaring_kind().is_some()
|| in_automatically_derived(cx.tcx, expr.hir_id)
{

View File

@ -14,7 +14,6 @@ use rustc_ast::token;
use rustc_ast::visit::FnKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_span::Span;
@ -350,7 +349,7 @@ impl EarlyLintPass for MiscEarlyLints {
}
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;
}
@ -387,7 +386,7 @@ impl EarlyLintPass for MiscEarlyLints {
}
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;
}

View File

@ -2,12 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use rustc_ast::{Pat, PatKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
use rustc_middle::lint::in_external_macro;
use super::REDUNDANT_AT_REST_PATTERN;
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 [one] = &**slice
&& let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind

View File

@ -8,7 +8,6 @@ use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
@ -106,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
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;
}

View File

@ -88,7 +88,7 @@ declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);
impl<'tcx> LateLintPass<'tcx> for MissingInline {
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;
}
@ -139,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
}
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;
}

View File

@ -6,7 +6,6 @@ use hir::{BlockCheckMode, ExprKind, QPath, UnOp};
use rustc_ast::Mutability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
use rustc_span::{DesugaringKind, Span};
@ -65,7 +64,7 @@ declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK])
impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
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)
{
return;

View File

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_hir};
use clippy_utils::higher;
use rustc_hir::{self as hir, AmbigArg, intravisit};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
@ -38,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
&& mty.mutbl == hir::Mutability::Mut
&& let hir::TyKind::Ref(_, mty) = mty.ty.kind
&& mty.mutbl == hir::Mutability::Mut
&& !in_external_macro(cx.sess(), ty.span)
&& !ty.span.in_external_macro(cx.sess().source_map())
{
span_lint(
cx,
@ -56,7 +55,7 @@ pub struct MutVisitor<'a, 'tcx> {
impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
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;
}

View File

@ -5,7 +5,6 @@ use clippy_utils::source::SpanRangeExt;
use rustc_errors::Applicability;
use rustc_hir::{ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -47,7 +46,7 @@ impl LateLintPass<'_> for NeedlessIf {
&& let ExprKind::Block(block, ..) = then.kind
&& block.stmts.is_empty()
&& 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| {
// Ignore
// - empty macro expansions

View File

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::implements_trait;
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_span::sym;
@ -48,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
if let ExprKind::Unary(UnOp::Not, inner) = expr.kind
&& let ExprKind::Binary(ref op, left, _) = inner.kind
&& 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);

View File

@ -6,7 +6,6 @@ use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::HirIdSet;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::sym;
@ -69,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
for assoc_item in *items {
if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
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;
}
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {

View File

@ -12,7 +12,6 @@ use rustc_hir::{
};
use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
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<'_>) {
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()
&& expr.span.ctxt() == ctxt
&& let Some(reduced) = reduce_expression(cx, expr)

View File

@ -5,7 +5,6 @@ use rustc_errors::Applicability;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::EarlyBinder;
use rustc_session::declare_lint_pass;
use rustc_span::sym;
@ -129,7 +128,7 @@ impl LateLintPass<'_> for NonCanonicalImpls {
let ExprKind::Block(block, ..) = body.value.kind else {
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;
}

View File

@ -5,7 +5,6 @@ use rustc_ast::ast::{
};
use rustc_ast::visit::{Visitor, walk_block, walk_expr, walk_pat};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{Span, sym};
@ -381,7 +380,7 @@ impl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {
impl EarlyLintPass for NonExpressiveNames {
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;
}
@ -396,7 +395,7 @@ impl EarlyLintPass for NonExpressiveNames {
}
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;
}

View File

@ -7,7 +7,6 @@ use rustc_ast::ImplPolarity;
use rustc_hir::def_id::DefId;
use rustc_hir::{FieldDef, Item, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, GenericArgKind, Ty};
use rustc_session::impl_lint_pass;
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
// single `AdtDef` may have multiple `Send` impls due to generic
// 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 ItemKind::Impl(hir_impl) = &item.kind
&& let Some(trait_ref) = &hir_impl.of_trait

View File

@ -9,7 +9,6 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::{self as hir, BodyId, Expr, ExprKind, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
@ -139,7 +138,7 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic {
return;
}
if in_external_macro(cx.sess(), item.span) {
if item.span.in_external_macro(cx.sess().source_map()) {
return;
}

View File

@ -4,7 +4,6 @@ use rustc_ast::token::LitKind;
use rustc_ast::{Expr, ExprKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_span::{BytePos, Pos, SpanData};
@ -59,7 +58,7 @@ impl EarlyLintPass for OctalEscapes {
LitKind::ByteStr | LitKind::CStr => 2,
_ => return,
})
&& !in_external_macro(cx.sess(), expr.span)
&& !expr.span.in_external_macro(cx.sess().source_map())
{
let s = lit.symbol.as_str();
let mut iter = s.as_bytes().iter();

View File

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
use clippy_utils::eq_expr_value;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PanickingOverflowChecks {
&& matches!(ty.kind(), ty::Uint(_))
&& ty == typeck.expr_ty(op_rhs)
&& 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)))
{
span_lint(

View File

@ -7,7 +7,6 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
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>) {
if let Some(init_expr) = local.init
&& 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)
&& 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 [name] = &path.segments
&& 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)
&& is_type_diagnostic_item(cx, ty, sym::PathBuf)
{

View File

@ -3,7 +3,6 @@ use rustc_hir::{
Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind, intravisit,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
use rustc_span::Span;
@ -84,7 +83,7 @@ declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);
impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
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;
}
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() {
return false;
}
if in_external_macro(cx.sess(), p.span) {
if p.span.in_external_macro(cx.sess().source_map()) {
return true;
}
let adjust_pat = match p.kind {

View File

@ -5,7 +5,6 @@ use rustc_ast::ast::{Expr, ExprKind};
use rustc_ast::token::LitKind;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::{BytePos, Pos, Span};
use std::iter::once;
@ -72,7 +71,7 @@ impl RawStrings {
impl EarlyLintPass for RawStrings {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
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'))
&& let Some(str) = snippet_opt(cx.sess(), format_args.span)
&& 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),
_ => 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))
{
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