mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Auto merge of #136448 - matthiaskrgr:rollup-pdim5di, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #134272 (Remove rustc_encodable_decodable feature) - #136283 (Update encode_utf16 to mention it is native endian) - #136394 (Clean up MonoItem::instantiation_mode) - #136402 (diagnostics: fix borrowck suggestions for if/while let conditionals) - #136415 (Highlight clarifying information in "expected/found" error) - #136422 (Convert two `rustc_middle::lint` functions to `Span` methods.) - #136434 (rustc_allowed_through_unstable_modules: require deprecation message) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4a43094662
@ -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>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)]`")
|
||||
|
@ -1,215 +0,0 @@
|
||||
//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{self as ast, Expr, MetaItem, Mutability};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Ident, Span, Symbol, sym};
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
|
||||
use crate::deriving::generic::ty::*;
|
||||
use crate::deriving::generic::*;
|
||||
use crate::deriving::pathvec_std;
|
||||
|
||||
pub(crate) fn expand_deriving_rustc_decodable(
|
||||
cx: &ExtCtxt<'_>,
|
||||
span: Span,
|
||||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let krate = sym::rustc_serialize;
|
||||
let typaram = sym::__D;
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
|
||||
skip_path_as_bound: false,
|
||||
needs_copy_as_bound_if_packed: true,
|
||||
additional_bounds: Vec::new(),
|
||||
supports_unions: false,
|
||||
methods: vec![MethodDef {
|
||||
name: sym::decode,
|
||||
generics: Bounds {
|
||||
bounds: vec![(typaram, vec![Path::new_(
|
||||
vec![krate, sym::Decoder],
|
||||
vec![],
|
||||
PathKind::Global,
|
||||
)])],
|
||||
},
|
||||
explicit_self: false,
|
||||
nonself_args: vec![(
|
||||
Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
|
||||
sym::d,
|
||||
)],
|
||||
ret_ty: Path(Path::new_(
|
||||
pathvec_std!(result::Result),
|
||||
vec![
|
||||
Box::new(Self_),
|
||||
Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))),
|
||||
],
|
||||
PathKind::Std,
|
||||
)),
|
||||
attributes: ast::AttrVec::new(),
|
||||
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
|
||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
||||
decodable_substructure(a, b, c, krate)
|
||||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
||||
fn decodable_substructure(
|
||||
cx: &ExtCtxt<'_>,
|
||||
trait_span: Span,
|
||||
substr: &Substructure<'_>,
|
||||
krate: Symbol,
|
||||
) -> BlockOrExpr {
|
||||
let decoder = substr.nonselflike_args[0].clone();
|
||||
let recurse = vec![
|
||||
Ident::new(krate, trait_span),
|
||||
Ident::new(sym::Decodable, trait_span),
|
||||
Ident::new(sym::decode, trait_span),
|
||||
];
|
||||
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
|
||||
// throw an underscore in front to suppress unused variable warnings
|
||||
let blkarg = Ident::new(sym::_d, trait_span);
|
||||
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
||||
|
||||
let expr = match substr.fields {
|
||||
StaticStruct(_, summary) => {
|
||||
let nfields = match summary {
|
||||
Unnamed(fields, _) => fields.len(),
|
||||
Named(fields) => fields.len(),
|
||||
};
|
||||
let fn_read_struct_field_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
|
||||
|
||||
let path = cx.path_ident(trait_span, substr.type_ident);
|
||||
let result =
|
||||
decode_static_fields(cx, trait_span, path, summary, |cx, span, name, field| {
|
||||
cx.expr_try(
|
||||
span,
|
||||
cx.expr_call_global(span, fn_read_struct_field_path.clone(), thin_vec![
|
||||
blkdecoder.clone(),
|
||||
cx.expr_str(span, name),
|
||||
cx.expr_usize(span, field),
|
||||
exprdecode.clone(),
|
||||
]),
|
||||
)
|
||||
});
|
||||
let result = cx.expr_ok(trait_span, result);
|
||||
let fn_read_struct_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct]);
|
||||
|
||||
cx.expr_call_global(trait_span, fn_read_struct_path, thin_vec![
|
||||
decoder,
|
||||
cx.expr_str(trait_span, substr.type_ident.name),
|
||||
cx.expr_usize(trait_span, nfields),
|
||||
cx.lambda1(trait_span, result, blkarg),
|
||||
])
|
||||
}
|
||||
StaticEnum(_, fields) => {
|
||||
let variant = Ident::new(sym::i, trait_span);
|
||||
|
||||
let mut arms = ThinVec::with_capacity(fields.len() + 1);
|
||||
let mut variants = ThinVec::with_capacity(fields.len());
|
||||
|
||||
let fn_read_enum_variant_arg_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant_arg]);
|
||||
|
||||
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
|
||||
variants.push(cx.expr_str(v_span, ident.name));
|
||||
|
||||
let path = cx.path(trait_span, vec![substr.type_ident, ident]);
|
||||
let decoded =
|
||||
decode_static_fields(cx, v_span, path, parts, |cx, span, _, field| {
|
||||
let idx = cx.expr_usize(span, field);
|
||||
cx.expr_try(
|
||||
span,
|
||||
cx.expr_call_global(
|
||||
span,
|
||||
fn_read_enum_variant_arg_path.clone(),
|
||||
thin_vec![blkdecoder.clone(), idx, exprdecode.clone()],
|
||||
),
|
||||
)
|
||||
});
|
||||
|
||||
arms.push(cx.arm(v_span, cx.pat_lit(v_span, cx.expr_usize(v_span, i)), decoded));
|
||||
}
|
||||
|
||||
arms.push(cx.arm_unreachable(trait_span));
|
||||
|
||||
let result = cx.expr_ok(
|
||||
trait_span,
|
||||
cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms),
|
||||
);
|
||||
let lambda = cx.lambda(trait_span, vec![blkarg, variant], result);
|
||||
let variant_array_ref = cx.expr_array_ref(trait_span, variants);
|
||||
let fn_read_enum_variant_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant]);
|
||||
let result = cx.expr_call_global(trait_span, fn_read_enum_variant_path, thin_vec![
|
||||
blkdecoder,
|
||||
variant_array_ref,
|
||||
lambda
|
||||
]);
|
||||
let fn_read_enum_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum]);
|
||||
|
||||
cx.expr_call_global(trait_span, fn_read_enum_path, thin_vec![
|
||||
decoder,
|
||||
cx.expr_str(trait_span, substr.type_ident.name),
|
||||
cx.lambda1(trait_span, result, blkarg),
|
||||
])
|
||||
}
|
||||
_ => cx.dcx().bug("expected StaticEnum or StaticStruct in derive(Decodable)"),
|
||||
};
|
||||
BlockOrExpr::new_expr(expr)
|
||||
}
|
||||
|
||||
/// Creates a decoder for a single enum variant/struct:
|
||||
/// - `outer_pat_path` is the path to this enum variant/struct
|
||||
/// - `getarg` should retrieve the `usize`-th field with name `@str`.
|
||||
fn decode_static_fields<F>(
|
||||
cx: &ExtCtxt<'_>,
|
||||
trait_span: Span,
|
||||
outer_pat_path: ast::Path,
|
||||
fields: &StaticFields,
|
||||
mut getarg: F,
|
||||
) -> P<Expr>
|
||||
where
|
||||
F: FnMut(&ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
|
||||
{
|
||||
match fields {
|
||||
Unnamed(fields, is_tuple) => {
|
||||
let path_expr = cx.expr_path(outer_pat_path);
|
||||
if matches!(is_tuple, IsTuple::No) {
|
||||
path_expr
|
||||
} else {
|
||||
let fields = fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &span)| getarg(cx, span, Symbol::intern(&format!("_field{i}")), i))
|
||||
.collect();
|
||||
|
||||
cx.expr_call(trait_span, path_expr, fields)
|
||||
}
|
||||
}
|
||||
Named(fields) => {
|
||||
// use the field's span to get nicer error messages.
|
||||
let fields = fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &(ident, span, _))| {
|
||||
let arg = getarg(cx, span, ident.name, i);
|
||||
cx.field_imm(span, ident, arg)
|
||||
})
|
||||
.collect();
|
||||
cx.expr_struct(trait_span, outer_pat_path, fields)
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_default(
|
||||
StaticStruct(_, fields) => {
|
||||
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)`"),
|
||||
|
@ -1,284 +0,0 @@
|
||||
//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
|
||||
//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
|
||||
//! type-defining items may be tagged with
|
||||
//! `#[derive(RustcEncodable, RustcDecodable)]`.
|
||||
//!
|
||||
//! For example, a type like:
|
||||
//!
|
||||
//! ```ignore (old code)
|
||||
//! #[derive(RustcEncodable, RustcDecodable)]
|
||||
//! struct Node { id: usize }
|
||||
//! ```
|
||||
//!
|
||||
//! would generate two implementations like:
|
||||
//!
|
||||
//! ```ignore (old code)
|
||||
//! # struct Node { id: usize }
|
||||
//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
|
||||
//! fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
//! s.emit_struct("Node", 1, |this| {
|
||||
//! this.emit_struct_field("id", 0, |this| {
|
||||
//! Encodable::encode(&self.id, this)
|
||||
//! /* this.emit_usize(self.id) can also be used */
|
||||
//! })
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
|
||||
//! fn decode(d: &mut D) -> Result<Node, E> {
|
||||
//! d.read_struct("Node", 1, |this| {
|
||||
//! match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
|
||||
//! Ok(id) => Ok(Node { id: id }),
|
||||
//! Err(e) => Err(e),
|
||||
//! }
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Other interesting scenarios are when the item has type parameters or
|
||||
//! references other non-built-in types. A type definition like:
|
||||
//!
|
||||
//! ```ignore (old code)
|
||||
//! # #[derive(RustcEncodable, RustcDecodable)]
|
||||
//! # struct Span;
|
||||
//! #[derive(RustcEncodable, RustcDecodable)]
|
||||
//! struct Spanned<T> { node: T, span: Span }
|
||||
//! ```
|
||||
//!
|
||||
//! would yield functions like:
|
||||
//!
|
||||
//! ```ignore (old code)
|
||||
//! # #[derive(RustcEncodable, RustcDecodable)]
|
||||
//! # struct Span;
|
||||
//! # struct Spanned<T> { node: T, span: Span }
|
||||
//! impl<
|
||||
//! S: Encoder<E>,
|
||||
//! E,
|
||||
//! T: Encodable<S, E>
|
||||
//! > Encodable<S, E> for Spanned<T> {
|
||||
//! fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
//! s.emit_struct("Spanned", 2, |this| {
|
||||
//! this.emit_struct_field("node", 0, |this| self.node.encode(this))
|
||||
//! .unwrap();
|
||||
//! this.emit_struct_field("span", 1, |this| self.span.encode(this))
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<
|
||||
//! D: Decoder<E>,
|
||||
//! E,
|
||||
//! T: Decodable<D, E>
|
||||
//! > Decodable<D, E> for Spanned<T> {
|
||||
//! fn decode(d: &mut D) -> Result<Spanned<T>, E> {
|
||||
//! d.read_struct("Spanned", 2, |this| {
|
||||
//! Ok(Spanned {
|
||||
//! node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
|
||||
//! .unwrap(),
|
||||
//! span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
|
||||
//! .unwrap(),
|
||||
//! })
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Ident, Span, Symbol, sym};
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
|
||||
use crate::deriving::generic::ty::*;
|
||||
use crate::deriving::generic::*;
|
||||
use crate::deriving::pathvec_std;
|
||||
|
||||
pub(crate) fn expand_deriving_rustc_encodable(
|
||||
cx: &ExtCtxt<'_>,
|
||||
span: Span,
|
||||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let krate = sym::rustc_serialize;
|
||||
let typaram = sym::__S;
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
|
||||
skip_path_as_bound: false,
|
||||
needs_copy_as_bound_if_packed: true,
|
||||
additional_bounds: Vec::new(),
|
||||
supports_unions: false,
|
||||
methods: vec![MethodDef {
|
||||
name: sym::encode,
|
||||
generics: Bounds {
|
||||
bounds: vec![(typaram, vec![Path::new_(
|
||||
vec![krate, sym::Encoder],
|
||||
vec![],
|
||||
PathKind::Global,
|
||||
)])],
|
||||
},
|
||||
explicit_self: true,
|
||||
nonself_args: vec![(
|
||||
Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
|
||||
sym::s,
|
||||
)],
|
||||
ret_ty: Path(Path::new_(
|
||||
pathvec_std!(result::Result),
|
||||
vec![
|
||||
Box::new(Unit),
|
||||
Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))),
|
||||
],
|
||||
PathKind::Std,
|
||||
)),
|
||||
attributes: AttrVec::new(),
|
||||
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
|
||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
||||
encodable_substructure(a, b, c, krate)
|
||||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
||||
fn encodable_substructure(
|
||||
cx: &ExtCtxt<'_>,
|
||||
trait_span: Span,
|
||||
substr: &Substructure<'_>,
|
||||
krate: Symbol,
|
||||
) -> BlockOrExpr {
|
||||
let encoder = substr.nonselflike_args[0].clone();
|
||||
// throw an underscore in front to suppress unused variable warnings
|
||||
let blkarg = Ident::new(sym::_e, trait_span);
|
||||
let blkencoder = cx.expr_ident(trait_span, blkarg);
|
||||
let fn_path = cx.expr_path(cx.path_global(trait_span, vec![
|
||||
Ident::new(krate, trait_span),
|
||||
Ident::new(sym::Encodable, trait_span),
|
||||
Ident::new(sym::encode, trait_span),
|
||||
]));
|
||||
|
||||
match substr.fields {
|
||||
Struct(_, fields) => {
|
||||
let fn_emit_struct_field_path =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
||||
let mut stmts = ThinVec::new();
|
||||
for (i, &FieldInfo { name, ref self_expr, span, .. }) in fields.iter().enumerate() {
|
||||
let name = match name {
|
||||
Some(id) => id.name,
|
||||
None => Symbol::intern(&format!("_field{i}")),
|
||||
};
|
||||
let self_ref = cx.expr_addr_of(span, self_expr.clone());
|
||||
let enc =
|
||||
cx.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
|
||||
let lambda = cx.lambda1(span, enc, blkarg);
|
||||
let call = cx.expr_call_global(span, fn_emit_struct_field_path.clone(), thin_vec![
|
||||
blkencoder.clone(),
|
||||
cx.expr_str(span, name),
|
||||
cx.expr_usize(span, i),
|
||||
lambda,
|
||||
]);
|
||||
|
||||
// last call doesn't need a try!
|
||||
let last = fields.len() - 1;
|
||||
let call = if i != last {
|
||||
cx.expr_try(span, call)
|
||||
} else {
|
||||
cx.expr(span, ExprKind::Ret(Some(call)))
|
||||
};
|
||||
|
||||
let stmt = cx.stmt_expr(call);
|
||||
stmts.push(stmt);
|
||||
}
|
||||
|
||||
// unit structs have no fields and need to return Ok()
|
||||
let blk = if stmts.is_empty() {
|
||||
let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
|
||||
cx.lambda1(trait_span, ok, blkarg)
|
||||
} else {
|
||||
cx.lambda_stmts_1(trait_span, stmts, blkarg)
|
||||
};
|
||||
|
||||
let fn_emit_struct_path =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct]);
|
||||
|
||||
let expr = cx.expr_call_global(trait_span, fn_emit_struct_path, thin_vec![
|
||||
encoder,
|
||||
cx.expr_str(trait_span, substr.type_ident.name),
|
||||
cx.expr_usize(trait_span, fields.len()),
|
||||
blk,
|
||||
]);
|
||||
BlockOrExpr::new_expr(expr)
|
||||
}
|
||||
|
||||
EnumMatching(idx, variant, fields) => {
|
||||
// We're not generating an AST that the borrow checker is expecting,
|
||||
// so we need to generate a unique local variable to take the
|
||||
// mutable loan out on, otherwise we get conflicts which don't
|
||||
// actually exist.
|
||||
let me = cx.stmt_let(trait_span, false, blkarg, encoder);
|
||||
let encoder = cx.expr_ident(trait_span, blkarg);
|
||||
|
||||
let fn_emit_enum_variant_arg_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant_arg]);
|
||||
|
||||
let mut stmts = ThinVec::new();
|
||||
if !fields.is_empty() {
|
||||
let last = fields.len() - 1;
|
||||
for (i, &FieldInfo { ref self_expr, span, .. }) in fields.iter().enumerate() {
|
||||
let self_ref = cx.expr_addr_of(span, self_expr.clone());
|
||||
let enc = cx
|
||||
.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
|
||||
let lambda = cx.lambda1(span, enc, blkarg);
|
||||
|
||||
let call = cx.expr_call_global(
|
||||
span,
|
||||
fn_emit_enum_variant_arg_path.clone(),
|
||||
thin_vec![blkencoder.clone(), cx.expr_usize(span, i), lambda],
|
||||
);
|
||||
let call = if i != last {
|
||||
cx.expr_try(span, call)
|
||||
} else {
|
||||
cx.expr(span, ExprKind::Ret(Some(call)))
|
||||
};
|
||||
stmts.push(cx.stmt_expr(call));
|
||||
}
|
||||
} else {
|
||||
let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
|
||||
let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
|
||||
stmts.push(cx.stmt_expr(ret_ok));
|
||||
}
|
||||
|
||||
let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
|
||||
let name = cx.expr_str(trait_span, variant.ident.name);
|
||||
|
||||
let fn_emit_enum_variant_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant]);
|
||||
|
||||
let call = cx.expr_call_global(trait_span, fn_emit_enum_variant_path, thin_vec![
|
||||
blkencoder,
|
||||
name,
|
||||
cx.expr_usize(trait_span, *idx),
|
||||
cx.expr_usize(trait_span, fields.len()),
|
||||
blk,
|
||||
]);
|
||||
|
||||
let blk = cx.lambda1(trait_span, call, blkarg);
|
||||
let fn_emit_enum_path: Vec<_> =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum]);
|
||||
let expr = cx.expr_call_global(trait_span, fn_emit_enum_path, thin_vec![
|
||||
encoder,
|
||||
cx.expr_str(trait_span, substr.type_ident.name),
|
||||
blk
|
||||
]);
|
||||
BlockOrExpr::new_mixed(thin_vec![me], Some(expr))
|
||||
}
|
||||
|
||||
_ => cx.dcx().bug("expected Struct or EnumMatching in derive(Encodable)"),
|
||||
}
|
||||
}
|
@ -311,7 +311,7 @@ pub(crate) enum SubstructureFields<'a> {
|
||||
/// Matching variants of the enum: variant index, ast::Variant,
|
||||
/// 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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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"]
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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(_))
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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((
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -314,8 +314,6 @@ symbols! {
|
||||
Right,
|
||||
Rust,
|
||||
RustaceansAreAwesome,
|
||||
RustcDecodable,
|
||||
RustcEncodable,
|
||||
RwLock,
|
||||
RwLockReadGuard,
|
||||
RwLockWriteGuard,
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -712,8 +712,8 @@ impl String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`]
|
||||
/// if `v` contains any invalid data.
|
||||
/// Decode a native endian UTF-16–encoded 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-16–encoded slice `v` into a `String`, replacing
|
||||
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
|
||||
/// Decode a native endian UTF-16–encoded 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-16LE–encoded vector `v` into a `String`, returning [`Err`]
|
||||
/// if `v` contains any invalid data.
|
||||
/// Decode a UTF-16LE–encoded vector `v` into a `String`,
|
||||
/// returning [`Err`] if `v` contains any invalid data.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -852,8 +852,8 @@ impl String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decode a UTF-16BE–encoded vector `v` into a `String`, returning [`Err`]
|
||||
/// if `v` contains any invalid data.
|
||||
/// Decode a UTF-16BE–encoded vector `v` into a `String`,
|
||||
/// returning [`Err`] if `v` contains any invalid data.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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")]
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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(
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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| {
|
||||
|
@ -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() {
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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, ..) => {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user