Auto merge of #148193 - camsteffen:remove-qpath-langitem, r=cjgillot
Remove `QPath::LangItem` Closes rust-lang/rust#115178. r? cjgillot
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
use crate::LoweringContext;
|
||||
@@ -128,7 +130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let req_span = self.mark_span_with_reason(
|
||||
rustc_span::DesugaringKind::Contract,
|
||||
lowered_req.span,
|
||||
None,
|
||||
Some(Arc::clone(&self.allow_contracts)),
|
||||
);
|
||||
let precond = self.expr_call_lang_item_fn_mut(
|
||||
req_span,
|
||||
@@ -143,8 +145,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ens: &Box<rustc_ast::Expr>,
|
||||
) -> &'hir rustc_hir::Expr<'hir> {
|
||||
let ens_span = self.lower_span(ens.span);
|
||||
let ens_span =
|
||||
self.mark_span_with_reason(rustc_span::DesugaringKind::Contract, ens_span, None);
|
||||
let ens_span = self.mark_span_with_reason(
|
||||
rustc_span::DesugaringKind::Contract,
|
||||
ens_span,
|
||||
Some(Arc::clone(&self.allow_contracts)),
|
||||
);
|
||||
let lowered_ens = self.lower_expr_mut(&ens);
|
||||
self.expr_call_lang_item_fn(
|
||||
ens_span,
|
||||
|
||||
@@ -865,6 +865,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
};
|
||||
|
||||
let features = match await_kind {
|
||||
FutureKind::Future if is_async_gen => Some(Arc::clone(&self.allow_async_gen)),
|
||||
FutureKind::Future => None,
|
||||
FutureKind::AsyncIterator => Some(Arc::clone(&self.allow_for_await)),
|
||||
};
|
||||
@@ -1479,7 +1480,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
|
||||
let e1 = self.lower_expr_mut(e1);
|
||||
let e2 = self.lower_expr_mut(e2);
|
||||
let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, span);
|
||||
let fn_path = self.make_lang_item_qpath(hir::LangItem::RangeInclusiveNew, span, None);
|
||||
let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path)));
|
||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||
}
|
||||
@@ -1565,7 +1566,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
|
||||
hir::ExprKind::Struct(
|
||||
self.arena.alloc(hir::QPath::LangItem(lang_item, span)),
|
||||
self.arena.alloc(self.make_lang_item_qpath(lang_item, span, None)),
|
||||
fields,
|
||||
hir::StructTailExpr::None,
|
||||
)
|
||||
@@ -1715,8 +1716,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
|
||||
// This ensures that we store our resumed `ResumeContext` correctly, and also that
|
||||
// the apparent value of the `yield` expression is `()`.
|
||||
let wrapped_yielded = self.expr_call_lang_item_fn(
|
||||
let desugar_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Async,
|
||||
span,
|
||||
Some(Arc::clone(&self.allow_async_gen)),
|
||||
);
|
||||
let wrapped_yielded = self.expr_call_lang_item_fn(
|
||||
desugar_span,
|
||||
hir::LangItem::AsyncGenReady,
|
||||
std::slice::from_ref(yielded),
|
||||
);
|
||||
@@ -1728,7 +1734,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
unreachable!("use of `await` outside of an async context.");
|
||||
};
|
||||
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
|
||||
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
||||
let lhs = self.expr_ident(desugar_span, task_context_ident, task_context_hid);
|
||||
|
||||
hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span))
|
||||
} else {
|
||||
@@ -2161,7 +2167,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
lang_item: hir::LangItem,
|
||||
fields: &'hir [hir::Expr<'hir>],
|
||||
) -> hir::Expr<'hir> {
|
||||
let path = self.arena.alloc(self.lang_item_path(span, lang_item));
|
||||
let path = self.arena.alloc(self.make_lang_item_qpath(lang_item, span, None));
|
||||
self.expr_enum_variant(span, path, fields)
|
||||
}
|
||||
|
||||
@@ -2198,16 +2204,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
) -> hir::Expr<'hir> {
|
||||
let path = self.lang_item_path(span, lang_item);
|
||||
self.expr(span, hir::ExprKind::Path(path))
|
||||
}
|
||||
|
||||
pub(super) fn lang_item_path(
|
||||
&mut self,
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
) -> hir::QPath<'hir> {
|
||||
hir::QPath::LangItem(lang_item, self.lower_span(span))
|
||||
let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
|
||||
self.expr(span, hir::ExprKind::Path(qpath))
|
||||
}
|
||||
|
||||
/// `<LangItem>::name`
|
||||
|
||||
@@ -391,7 +391,8 @@ fn make_format_spec<'hir>(
|
||||
let flags = ctx.expr_field(Ident::new(sym::flags, sp), ctx.arena.alloc(flags), sp);
|
||||
let precision = ctx.expr_field(Ident::new(sym::precision, sp), ctx.arena.alloc(precision), sp);
|
||||
let width = ctx.expr_field(Ident::new(sym::width, sp), ctx.arena.alloc(width), sp);
|
||||
let placeholder = ctx.arena.alloc(hir::QPath::LangItem(hir::LangItem::FormatPlaceholder, sp));
|
||||
let placeholder =
|
||||
ctx.arena.alloc(ctx.make_lang_item_qpath(hir::LangItem::FormatPlaceholder, sp, None));
|
||||
let fields = ctx.arena.alloc_from_iter([position, flags, precision, width]);
|
||||
ctx.expr(sp, hir::ExprKind::Struct(placeholder, fields, hir::StructTailExpr::None))
|
||||
}
|
||||
|
||||
@@ -138,9 +138,11 @@ struct LoweringContext<'a, 'hir> {
|
||||
#[cfg(debug_assertions)]
|
||||
node_id_to_local_id: NodeMap<hir::ItemLocalId>,
|
||||
|
||||
allow_contracts: Arc<[Symbol]>,
|
||||
allow_try_trait: Arc<[Symbol]>,
|
||||
allow_gen_future: Arc<[Symbol]>,
|
||||
allow_pattern_type: Arc<[Symbol]>,
|
||||
allow_async_gen: Arc<[Symbol]>,
|
||||
allow_async_iterator: Arc<[Symbol]>,
|
||||
allow_for_await: Arc<[Symbol]>,
|
||||
allow_async_fn_traits: Arc<[Symbol]>,
|
||||
@@ -183,6 +185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
current_item: None,
|
||||
impl_trait_defs: Vec::new(),
|
||||
impl_trait_bounds: Vec::new(),
|
||||
allow_contracts: [sym::contracts_internals].into(),
|
||||
allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
|
||||
allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
|
||||
allow_gen_future: if tcx.features().async_fn_track_caller() {
|
||||
@@ -190,8 +193,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
} else {
|
||||
[sym::gen_future].into()
|
||||
},
|
||||
allow_for_await: [sym::async_iterator].into(),
|
||||
allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),
|
||||
allow_async_fn_traits: [sym::async_fn_traits].into(),
|
||||
allow_async_gen: [sym::async_gen_internals].into(),
|
||||
// FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`
|
||||
// interact with `gen`/`async gen` blocks
|
||||
allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
|
||||
@@ -2531,8 +2535,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
lang_item: hir::LangItem,
|
||||
fields: &'hir [hir::PatField<'hir>],
|
||||
) -> &'hir hir::Pat<'hir> {
|
||||
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
|
||||
self.pat(span, hir::PatKind::Struct(qpath, fields, None))
|
||||
let path = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
|
||||
self.pat(span, hir::PatKind::Struct(path, fields, None))
|
||||
}
|
||||
|
||||
fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
|
||||
|
||||
@@ -503,8 +503,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
}
|
||||
if let hir::Node::Expr(parent_expr) = parent
|
||||
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
|
||||
call_expr.kind
|
||||
&& let hir::ExprKind::Path(qpath) = call_expr.kind
|
||||
&& tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)
|
||||
{
|
||||
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
|
||||
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
|
||||
@@ -2312,6 +2312,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
let typeck_results = tcx.typeck(self.mir_def_id());
|
||||
|
||||
struct ExprFinder<'hir> {
|
||||
tcx: TyCtxt<'hir>,
|
||||
issue_span: Span,
|
||||
expr_span: Span,
|
||||
body_expr: Option<&'hir hir::Expr<'hir>>,
|
||||
@@ -2336,9 +2337,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
// };
|
||||
// corresponding to the desugaring of a for loop `for <pat> in <head> { <body> }`.
|
||||
if let hir::ExprKind::Call(path, [arg]) = ex.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
|
||||
path.kind
|
||||
&& let hir::ExprKind::Path(qpath) = path.kind
|
||||
&& self.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)
|
||||
&& arg.span.contains(self.issue_span)
|
||||
&& ex.span.desugaring_kind() == Some(DesugaringKind::ForLoop)
|
||||
{
|
||||
// Find `IntoIterator::into_iter(<head>)`
|
||||
self.head = Some(arg);
|
||||
@@ -2355,10 +2357,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
..
|
||||
}) = stmt.kind
|
||||
&& let hir::ExprKind::Call(path, _args) = call.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IteratorNext, _)) =
|
||||
path.kind
|
||||
&& let hir::PatKind::Struct(path, [field, ..], _) = bind.pat.kind
|
||||
&& let hir::QPath::LangItem(LangItem::OptionSome, pat_span) = path
|
||||
&& let hir::ExprKind::Path(qpath) = path.kind
|
||||
&& self.tcx.qpath_is_lang_item(qpath, LangItem::IteratorNext)
|
||||
&& let hir::PatKind::Struct(qpath, [field, ..], _) = bind.pat.kind
|
||||
&& self.tcx.qpath_is_lang_item(qpath, LangItem::OptionSome)
|
||||
&& call.span.contains(self.issue_span)
|
||||
{
|
||||
// Find `<pat>` and the span for the whole `for` loop.
|
||||
@@ -2370,7 +2372,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
self.loop_bind = Some(ident);
|
||||
}
|
||||
self.head_span = Some(*head_span);
|
||||
self.pat_span = Some(pat_span);
|
||||
self.pat_span = Some(bind.pat.span);
|
||||
self.loop_span = Some(stmt.span);
|
||||
}
|
||||
|
||||
@@ -2385,6 +2387,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
let mut finder = ExprFinder {
|
||||
tcx,
|
||||
expr_span: span,
|
||||
issue_span,
|
||||
loop_bind: None,
|
||||
|
||||
@@ -23,13 +23,14 @@ use rustc_index::IndexVec;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
|
||||
use rustc_span::{
|
||||
BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Symbol, kw, sym,
|
||||
};
|
||||
use rustc_target::asm::InlineAsmRegOrRegClass;
|
||||
use smallvec::SmallVec;
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::LangItem;
|
||||
use crate::attrs::AttributeKind;
|
||||
use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res};
|
||||
use crate::def_id::{DefId, LocalDefIdMap};
|
||||
@@ -2418,9 +2419,6 @@ impl Expr<'_> {
|
||||
allow_projections_from(base) || base.is_place_expr(allow_projections_from)
|
||||
}
|
||||
|
||||
// Lang item paths cannot currently be local variables or statics.
|
||||
ExprKind::Path(QPath::LangItem(..)) => false,
|
||||
|
||||
// Suppress errors for bad expressions.
|
||||
ExprKind::Err(_guar)
|
||||
| ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,
|
||||
@@ -2590,112 +2588,27 @@ impl Expr<'_> {
|
||||
pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
|
||||
match (self.kind, other.kind) {
|
||||
(ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
|
||||
(
|
||||
ExprKind::Path(QPath::LangItem(item1, _)),
|
||||
ExprKind::Path(QPath::LangItem(item2, _)),
|
||||
) => item1 == item2,
|
||||
(
|
||||
ExprKind::Path(QPath::Resolved(None, path1)),
|
||||
ExprKind::Path(QPath::Resolved(None, path2)),
|
||||
) => path1.res == path2.res,
|
||||
(
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeTo, _),
|
||||
[val1],
|
||||
&QPath::Resolved(None, &Path { res: Res::Def(_, path1_def_id), .. }),
|
||||
args1,
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeTo, _),
|
||||
[val2],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
)
|
||||
| (
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeToInclusive, _),
|
||||
[val1],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeToInclusive, _),
|
||||
[val2],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
)
|
||||
| (
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
|
||||
[val1],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
|
||||
[val2],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
)
|
||||
| (
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeFrom, _),
|
||||
[val1],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeFrom, _),
|
||||
[val2],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
)
|
||||
| (
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeFromCopy, _),
|
||||
[val1],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeFromCopy, _),
|
||||
[val2],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
) => val1.expr.equivalent_for_indexing(val2.expr),
|
||||
(
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::Range, _),
|
||||
[val1, val3],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::Range, _),
|
||||
[val2, val4],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
)
|
||||
| (
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeCopy, _),
|
||||
[val1, val3],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeCopy, _),
|
||||
[val2, val4],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
)
|
||||
| (
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeInclusiveCopy, _),
|
||||
[val1, val3],
|
||||
StructTailExpr::None,
|
||||
),
|
||||
ExprKind::Struct(
|
||||
QPath::LangItem(LangItem::RangeInclusiveCopy, _),
|
||||
[val2, val4],
|
||||
&QPath::Resolved(None, &Path { res: Res::Def(_, path2_def_id), .. }),
|
||||
args2,
|
||||
StructTailExpr::None,
|
||||
),
|
||||
) => {
|
||||
val1.expr.equivalent_for_indexing(val2.expr)
|
||||
&& val3.expr.equivalent_for_indexing(val4.expr)
|
||||
path2_def_id == path1_def_id
|
||||
&& is_range_literal(self)
|
||||
&& is_range_literal(other)
|
||||
&& std::iter::zip(args1, args2)
|
||||
.all(|(a, b)| a.expr.equivalent_for_indexing(b.expr))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@@ -2713,30 +2626,29 @@ impl Expr<'_> {
|
||||
/// Checks if the specified expression is a built-in range literal.
|
||||
/// (See: `LoweringContext::lower_expr()`).
|
||||
pub fn is_range_literal(expr: &Expr<'_>) -> bool {
|
||||
match expr.kind {
|
||||
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
|
||||
ExprKind::Struct(ref qpath, _, _) => matches!(
|
||||
**qpath,
|
||||
QPath::LangItem(
|
||||
LangItem::Range
|
||||
| LangItem::RangeTo
|
||||
| LangItem::RangeFrom
|
||||
| LangItem::RangeFull
|
||||
| LangItem::RangeToInclusive
|
||||
| LangItem::RangeCopy
|
||||
| LangItem::RangeFromCopy
|
||||
| LangItem::RangeInclusiveCopy
|
||||
| LangItem::RangeToInclusiveCopy,
|
||||
..
|
||||
)
|
||||
),
|
||||
|
||||
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
||||
ExprKind::Call(ref func, _) => {
|
||||
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
|
||||
}
|
||||
|
||||
_ => false,
|
||||
if let ExprKind::Struct(QPath::Resolved(None, path), _, StructTailExpr::None) = expr.kind
|
||||
&& let [.., segment] = path.segments
|
||||
&& let sym::RangeFrom
|
||||
| sym::RangeFull
|
||||
| sym::Range
|
||||
| sym::RangeToInclusive
|
||||
| sym::RangeTo
|
||||
| sym::RangeFromCopy
|
||||
| sym::RangeCopy
|
||||
| sym::RangeInclusiveCopy
|
||||
| sym::RangeToInclusiveCopy = segment.ident.name
|
||||
&& expr.span.is_desugaring(DesugaringKind::RangeExpr)
|
||||
{
|
||||
true
|
||||
} else if let ExprKind::Call(func, _) = &expr.kind
|
||||
&& let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
|
||||
&& let [.., segment] = path.segments
|
||||
&& let sym::range_inclusive_new = segment.ident.name
|
||||
&& expr.span.is_desugaring(DesugaringKind::RangeExpr)
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2930,9 +2842,6 @@ pub enum QPath<'hir> {
|
||||
/// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
|
||||
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
|
||||
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
|
||||
|
||||
/// Reference to a `#[lang = "foo"]` item.
|
||||
LangItem(LangItem, Span),
|
||||
}
|
||||
|
||||
impl<'hir> QPath<'hir> {
|
||||
@@ -2941,7 +2850,6 @@ impl<'hir> QPath<'hir> {
|
||||
match *self {
|
||||
QPath::Resolved(_, path) => path.span,
|
||||
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
|
||||
QPath::LangItem(_, span) => span,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2951,7 +2859,6 @@ impl<'hir> QPath<'hir> {
|
||||
match *self {
|
||||
QPath::Resolved(_, path) => path.span,
|
||||
QPath::TypeRelative(qself, _) => qself.span,
|
||||
QPath::LangItem(_, span) => span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1416,7 +1416,6 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(
|
||||
try_visit!(visitor.visit_ty_unambig(qself));
|
||||
visitor.visit_path_segment(segment)
|
||||
}
|
||||
QPath::LangItem(..) => V::Result::output(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2240,13 +2240,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
)
|
||||
.unwrap_or_else(|guar| Const::new_error(tcx, guar))
|
||||
}
|
||||
hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => {
|
||||
ty::Const::new_error_with_message(
|
||||
tcx,
|
||||
qpath.span(),
|
||||
format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
|
||||
)
|
||||
}
|
||||
hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
|
||||
hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
|
||||
}
|
||||
@@ -2561,17 +2554,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
.map(|(ty, _, _)| ty)
|
||||
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
|
||||
}
|
||||
&hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
|
||||
let def_id = tcx.require_lang_item(lang_item, span);
|
||||
let (args, _) = self.lower_generic_args_of_path(
|
||||
span,
|
||||
def_id,
|
||||
&[],
|
||||
&hir::PathSegment::invalid(),
|
||||
None,
|
||||
);
|
||||
tcx.at(span).type_of(def_id).instantiate(tcx, args)
|
||||
}
|
||||
hir::TyKind::Array(ty, length) => {
|
||||
let length = self.lower_const_arg(length, FeedConstTy::No);
|
||||
Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
|
||||
|
||||
@@ -1774,11 +1774,6 @@ impl<'a> State<'a> {
|
||||
self.print_ident(item_segment.ident);
|
||||
self.print_generic_args(item_segment.args(), colons_before_params)
|
||||
}
|
||||
hir::QPath::LangItem(lang_item, span) => {
|
||||
self.word("#[lang = \"");
|
||||
self.print_ident(Ident::new(lang_item.name(), span));
|
||||
self.word("\"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1196,6 +1196,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr.hir_id) else {
|
||||
return;
|
||||
};
|
||||
if parent_expr.span.desugaring_kind().is_some() {
|
||||
return;
|
||||
}
|
||||
enum CallableKind {
|
||||
Function,
|
||||
Method,
|
||||
|
||||
@@ -19,7 +19,7 @@ use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{ExprKind, HirId, QPath, find_attr};
|
||||
use rustc_hir::{ExprKind, HirId, QPath, find_attr, is_range_literal};
|
||||
use rustc_hir_analysis::NoVariantNamed;
|
||||
use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _};
|
||||
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin};
|
||||
@@ -545,9 +545,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ExprKind::AddrOf(kind, mutbl, oprnd) => {
|
||||
self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
|
||||
}
|
||||
ExprKind::Path(QPath::LangItem(lang_item, _)) => {
|
||||
self.check_lang_item_path(lang_item, expr)
|
||||
}
|
||||
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None),
|
||||
ExprKind::InlineAsm(asm) => {
|
||||
// We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
|
||||
@@ -748,14 +745,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_lang_item_path(
|
||||
&self,
|
||||
lang_item: hir::LangItem,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1
|
||||
}
|
||||
|
||||
pub(crate) fn check_expr_path(
|
||||
&self,
|
||||
qpath: &'tcx hir::QPath<'tcx>,
|
||||
@@ -763,6 +752,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
call_expr_and_args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
if let Some((_, [arg])) = call_expr_and_args
|
||||
&& let QPath::Resolved(_, path) = qpath
|
||||
&& let Res::Def(_, def_id) = path.res
|
||||
&& let Some(lang_item) = tcx.lang_items().from_def_id(def_id)
|
||||
{
|
||||
let code = match lang_item {
|
||||
LangItem::IntoFutureIntoFuture
|
||||
if expr.span.is_desugaring(DesugaringKind::Await) =>
|
||||
{
|
||||
Some(ObligationCauseCode::AwaitableExpr(arg.hir_id))
|
||||
}
|
||||
LangItem::IntoIterIntoIter | LangItem::IteratorNext
|
||||
if expr.span.is_desugaring(DesugaringKind::ForLoop) =>
|
||||
{
|
||||
Some(ObligationCauseCode::ForLoopIterator)
|
||||
}
|
||||
LangItem::TryTraitFromOutput
|
||||
if expr.span.is_desugaring(DesugaringKind::TryBlock) =>
|
||||
{
|
||||
// FIXME it's a try block, not a question mark
|
||||
Some(ObligationCauseCode::QuestionMark)
|
||||
}
|
||||
LangItem::TryTraitBranch | LangItem::TryTraitFromResidual
|
||||
if expr.span.is_desugaring(DesugaringKind::QuestionMark) =>
|
||||
{
|
||||
Some(ObligationCauseCode::QuestionMark)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if let Some(code) = code {
|
||||
let args = self.fresh_args_for_item(expr.span, def_id);
|
||||
self.add_required_obligations_with_code(expr.span, def_id, args, |_, _| {
|
||||
code.clone()
|
||||
});
|
||||
return tcx.type_of(def_id).instantiate(tcx, args);
|
||||
}
|
||||
}
|
||||
|
||||
let (res, opt_ty, segs) =
|
||||
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
|
||||
let ty = match res {
|
||||
@@ -2483,9 +2511,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
args: GenericArgsRef<'tcx>,
|
||||
mut err: Diag<'_>,
|
||||
) {
|
||||
// I don't use 'is_range_literal' because only double-sided, half-open ranges count.
|
||||
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [range_start, range_end], _) =
|
||||
last_expr_field.expr.kind
|
||||
if is_range_literal(last_expr_field.expr)
|
||||
&& let ExprKind::Struct(&qpath, [range_start, range_end], _) = last_expr_field.expr.kind
|
||||
&& self.tcx.qpath_is_lang_item(qpath, LangItem::Range)
|
||||
&& let variant_field =
|
||||
variant.fields.iter().find(|field| field.ident(self.tcx) == last_expr_field.ident)
|
||||
&& let range_def_id = self.tcx.lang_items().range_struct()
|
||||
|
||||
@@ -671,9 +671,6 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
|
||||
path.segments.last().expect("paths should have a segment")
|
||||
}
|
||||
hir::QPath::TypeRelative(_, segment) => segment,
|
||||
hir::QPath::LangItem(..) => {
|
||||
return hir::intravisit::walk_qpath(self, qpath, id);
|
||||
}
|
||||
};
|
||||
// Alternatively, try to turbofish `::<_, (), _>`.
|
||||
if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id()
|
||||
|
||||
@@ -691,53 +691,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
vec![ty_error; len]
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_lang_item_path(
|
||||
&self,
|
||||
lang_item: hir::LangItem,
|
||||
span: Span,
|
||||
hir_id: HirId,
|
||||
) -> (Res, Ty<'tcx>) {
|
||||
let def_id = self.tcx.require_lang_item(lang_item, span);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
|
||||
let item_ty = if let DefKind::Variant = def_kind {
|
||||
self.tcx.type_of(self.tcx.parent(def_id))
|
||||
} else {
|
||||
self.tcx.type_of(def_id)
|
||||
};
|
||||
let args = self.fresh_args_for_item(span, def_id);
|
||||
let ty = item_ty.instantiate(self.tcx, args);
|
||||
|
||||
self.write_args(hir_id, args);
|
||||
self.write_resolution(hir_id, Ok((def_kind, def_id)));
|
||||
|
||||
let code = match lang_item {
|
||||
hir::LangItem::IntoFutureIntoFuture => {
|
||||
if let hir::Node::Expr(into_future_call) = self.tcx.parent_hir_node(hir_id)
|
||||
&& let hir::ExprKind::Call(_, [arg0]) = &into_future_call.kind
|
||||
{
|
||||
Some(ObligationCauseCode::AwaitableExpr(arg0.hir_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
|
||||
Some(ObligationCauseCode::ForLoopIterator)
|
||||
}
|
||||
hir::LangItem::TryTraitFromOutput
|
||||
| hir::LangItem::TryTraitFromResidual
|
||||
| hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(code) = code {
|
||||
self.add_required_obligations_with_code(span, def_id, args, move |_, _| code.clone());
|
||||
} else {
|
||||
self.add_required_obligations_for_hir(span, def_id, args, hir_id);
|
||||
}
|
||||
|
||||
(Res::Def(def_kind, def_id), ty)
|
||||
}
|
||||
|
||||
/// Resolves an associated value path into a base type and associated constant, or method
|
||||
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
@@ -768,9 +721,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ty = self.lowerer().lower_ty(qself);
|
||||
(LoweredTy::from_raw(self, span, ty), qself, segment)
|
||||
}
|
||||
QPath::LangItem(..) => {
|
||||
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
|
||||
}
|
||||
};
|
||||
|
||||
self.register_wf_obligation(
|
||||
@@ -1035,8 +985,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// inherent impl, we need to record the
|
||||
// `T` for posterity (see `UserSelfTy` for
|
||||
// details).
|
||||
let self_ty = self_ty.expect("UFCS sugared assoc missing Self").raw;
|
||||
user_self_ty = Some(UserSelfTy { impl_def_id: container_id, self_ty });
|
||||
// Generated desugaring code may have a path without a self.
|
||||
user_self_ty = self_ty.map(|self_ty| UserSelfTy {
|
||||
impl_def_id: container_id,
|
||||
self_ty: self_ty.raw,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1374,7 +1327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, code, span, args))]
|
||||
fn add_required_obligations_with_code(
|
||||
pub(crate) fn add_required_obligations_with_code(
|
||||
&self,
|
||||
span: Span,
|
||||
def_id: DefId,
|
||||
|
||||
@@ -419,7 +419,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
false
|
||||
|
||||
@@ -8,7 +8,7 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, lis
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{Expr, ExprKind, HirId, LangItem, Node, QPath};
|
||||
use rustc_hir::{Expr, ExprKind, HirId, LangItem, Node, QPath, is_range_literal};
|
||||
use rustc_hir_analysis::check::potentially_plural_count;
|
||||
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, PermitVariants};
|
||||
use rustc_index::IndexVec;
|
||||
@@ -1290,10 +1290,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
(result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
|
||||
}
|
||||
QPath::LangItem(lang_item, span) => {
|
||||
let (res, ty) = self.resolve_lang_item_path(lang_item, span, hir_id);
|
||||
(res, LoweredTy::from_raw(self, path_span, ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2051,8 +2047,9 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> {
|
||||
fn detect_dotdot(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, expr: &hir::Expr<'tcx>) {
|
||||
if let ty::Adt(adt, _) = ty.kind()
|
||||
&& self.tcx().is_lang_item(adt.did(), hir::LangItem::RangeFull)
|
||||
&& let hir::ExprKind::Struct(hir::QPath::LangItem(hir::LangItem::RangeFull, _), [], _) =
|
||||
expr.kind
|
||||
&& is_range_literal(expr)
|
||||
&& let hir::ExprKind::Struct(&path, [], _) = expr.kind
|
||||
&& self.tcx().qpath_is_lang_item(path, hir::LangItem::RangeFull)
|
||||
{
|
||||
// We have `Foo(a, .., c)`, where the user might be trying to use the "rest" syntax
|
||||
// from default field values, which is not supported on tuples.
|
||||
|
||||
@@ -11,7 +11,7 @@ use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{
|
||||
self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind,
|
||||
GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind,
|
||||
WherePredicateKind, expr_needs_parens,
|
||||
WherePredicateKind, expr_needs_parens, is_range_literal,
|
||||
};
|
||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||
use rustc_hir_analysis::suggest_impl_trait;
|
||||
@@ -1664,7 +1664,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return false;
|
||||
}
|
||||
match expr.kind {
|
||||
ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, end], _) => {
|
||||
ExprKind::Struct(&qpath, [start, end], _)
|
||||
if is_range_literal(expr)
|
||||
&& self.tcx.qpath_is_lang_item(qpath, LangItem::Range) =>
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
start.expr.span.shrink_to_hi().with_hi(end.expr.span.lo()),
|
||||
"remove the unnecessary `.` operator for a floating point literal",
|
||||
@@ -1673,24 +1676,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
true
|
||||
}
|
||||
ExprKind::Struct(QPath::LangItem(LangItem::RangeFrom, ..), [start], _) => {
|
||||
ExprKind::Struct(&qpath, [arg], _)
|
||||
if is_range_literal(expr)
|
||||
&& let Some(qpath @ (LangItem::RangeFrom | LangItem::RangeTo)) =
|
||||
self.tcx.qpath_lang_item(qpath) =>
|
||||
{
|
||||
let range_span = expr.span.parent_callsite().unwrap();
|
||||
err.span_suggestion_verbose(
|
||||
range_span.with_lo(start.expr.span.hi()),
|
||||
"remove the unnecessary `.` operator for a floating point literal",
|
||||
'.',
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
true
|
||||
}
|
||||
ExprKind::Struct(QPath::LangItem(LangItem::RangeTo, ..), [end], _) => {
|
||||
let range_span = expr.span.parent_callsite().unwrap();
|
||||
err.span_suggestion_verbose(
|
||||
range_span.until(end.expr.span),
|
||||
"remove the unnecessary `.` operator and add an integer part for a floating point literal",
|
||||
"0.",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
match qpath {
|
||||
LangItem::RangeFrom => {
|
||||
err.span_suggestion_verbose(
|
||||
range_span.with_lo(arg.expr.span.hi()),
|
||||
"remove the unnecessary `.` operator for a floating point literal",
|
||||
'.',
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
err.span_suggestion_verbose(
|
||||
range_span.until(arg.expr.span),
|
||||
"remove the unnecessary `.` operator and add an integer part for a floating point literal",
|
||||
"0.",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
ExprKind::Lit(Spanned {
|
||||
@@ -3497,11 +3506,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if !hir::is_range_literal(expr) {
|
||||
return;
|
||||
}
|
||||
let hir::ExprKind::Struct(hir::QPath::LangItem(LangItem::Range, ..), [start, end], _) =
|
||||
expr.kind
|
||||
else {
|
||||
let hir::ExprKind::Struct(&qpath, [start, end], _) = expr.kind else {
|
||||
return;
|
||||
};
|
||||
if !self.tcx.qpath_is_lang_item(qpath, LangItem::Range) {
|
||||
return;
|
||||
}
|
||||
if let hir::Node::ExprField(_) = self.tcx.parent_hir_node(expr.hir_id) {
|
||||
// Ignore `Foo { field: a..Default::default() }`
|
||||
return;
|
||||
|
||||
@@ -19,7 +19,9 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{self as hir, ExprKind, HirId, Node, PathSegment, QPath, find_attr};
|
||||
use rustc_hir::{
|
||||
self as hir, ExprKind, HirId, Node, PathSegment, QPath, find_attr, is_range_literal,
|
||||
};
|
||||
use rustc_infer::infer::{BoundRegionConversionTime, RegionVariableOrigin};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
|
||||
@@ -2412,22 +2414,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let SelfSource::MethodCall(expr) = source {
|
||||
for (_, parent) in tcx.hir_parent_iter(expr.hir_id).take(5) {
|
||||
if let Node::Expr(parent_expr) = parent {
|
||||
if !is_range_literal(parent_expr) {
|
||||
continue;
|
||||
}
|
||||
let lang_item = match parent_expr.kind {
|
||||
ExprKind::Struct(qpath, _, _) => match *qpath {
|
||||
QPath::LangItem(LangItem::Range, ..) => Some(LangItem::Range),
|
||||
QPath::LangItem(LangItem::RangeCopy, ..) => Some(LangItem::RangeCopy),
|
||||
QPath::LangItem(LangItem::RangeInclusiveCopy, ..) => {
|
||||
Some(LangItem::RangeInclusiveCopy)
|
||||
}
|
||||
QPath::LangItem(LangItem::RangeTo, ..) => Some(LangItem::RangeTo),
|
||||
QPath::LangItem(LangItem::RangeToInclusive, ..) => {
|
||||
Some(LangItem::RangeToInclusive)
|
||||
}
|
||||
ExprKind::Struct(qpath, _, _) => match tcx.qpath_lang_item(*qpath) {
|
||||
Some(
|
||||
lang_item @ (LangItem::Range
|
||||
| LangItem::RangeCopy
|
||||
| LangItem::RangeInclusiveCopy
|
||||
| LangItem::RangeTo
|
||||
| LangItem::RangeToInclusive),
|
||||
) => Some(lang_item),
|
||||
_ => None,
|
||||
},
|
||||
ExprKind::Call(func, _) => match func.kind {
|
||||
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
||||
ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)) => {
|
||||
ExprKind::Path(qpath)
|
||||
if tcx.qpath_is_lang_item(qpath, LangItem::RangeInclusiveNew) =>
|
||||
{
|
||||
Some(LangItem::RangeInclusiveStruct)
|
||||
}
|
||||
_ => None,
|
||||
|
||||
@@ -718,7 +718,7 @@ impl<'tcx> LateContext<'tcx> {
|
||||
pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
|
||||
match *qpath {
|
||||
hir::QPath::Resolved(_, path) => path.res,
|
||||
hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
|
||||
hir::QPath::TypeRelative(..) => self
|
||||
.maybe_typeck_results()
|
||||
.filter(|typeck_results| typeck_results.hir_owner == id.owner)
|
||||
.or_else(|| {
|
||||
|
||||
@@ -132,8 +132,8 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter {
|
||||
&& let hir::ExprKind::Match(arg, [_], hir::MatchSource::ForLoopDesugar) =
|
||||
&parent_expr.kind
|
||||
&& let hir::ExprKind::Call(path, [_]) = &arg.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoIterIntoIter, ..)) =
|
||||
&path.kind
|
||||
&& let hir::ExprKind::Path(qpath) = path.kind
|
||||
&& cx.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)
|
||||
{
|
||||
Some(ShadowedIntoIterDiagSub::RemoveIntoIter {
|
||||
span: receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
|
||||
|
||||
@@ -2598,8 +2598,6 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body<'_>, def_id: Loc
|
||||
// FIXME: Claiming that those kinds of QPaths are simple is probably not true if the Ty
|
||||
// contains const arguments. Is there a *concise* way to check for this?
|
||||
hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => Simple,
|
||||
// FIXME: Can they contain const arguments and thus leak private struct fields?
|
||||
hir::ExprKind::Path(hir::QPath::LangItem(..)) => Simple,
|
||||
_ => Complex,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::lints::DelayedLint;
|
||||
use rustc_hir::*;
|
||||
@@ -203,6 +203,20 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn qpath_is_lang_item(self, qpath: QPath<'_>, lang_item: LangItem) -> bool {
|
||||
self.qpath_lang_item(qpath) == Some(lang_item)
|
||||
}
|
||||
|
||||
/// This does not use typeck results since this is intended to be used with generated code.
|
||||
pub fn qpath_lang_item(self, qpath: QPath<'_>) -> Option<LangItem> {
|
||||
if let QPath::Resolved(_, path) = qpath
|
||||
&& let Res::Def(_, def_id) = path.res
|
||||
{
|
||||
return self.lang_items().from_def_id(def_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Hashes computed by [`TyCtxt::hash_owner_nodes`] if necessary.
|
||||
|
||||
@@ -266,7 +266,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
||||
pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: HirId) -> Res {
|
||||
match *qpath {
|
||||
hir::QPath::Resolved(_, path) => path.res,
|
||||
hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
|
||||
hir::QPath::TypeRelative(..) => self
|
||||
.type_dependent_def(id)
|
||||
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
|
||||
}
|
||||
|
||||
@@ -425,7 +425,6 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -1268,7 +1268,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||
Res::Def(kind, def_id) => Some((kind, def_id)),
|
||||
_ => None,
|
||||
},
|
||||
hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => {
|
||||
hir::QPath::TypeRelative(..) => {
|
||||
match self.maybe_typeck_results {
|
||||
Some(typeck_results) => typeck_results.type_dependent_def(id),
|
||||
// FIXME: Check type-relative associated types in signatures.
|
||||
@@ -1287,9 +1287,6 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||
if let DefKind::Static { .. } = kind { def_id.is_local() } else { false };
|
||||
if !self.item_is_accessible(def_id) && !is_local_static {
|
||||
let name = match *qpath {
|
||||
hir::QPath::LangItem(it, ..) => {
|
||||
self.tcx.lang_items().get(it).map(|did| self.tcx.def_path_str(did))
|
||||
}
|
||||
hir::QPath::Resolved(_, path) => Some(self.tcx.def_path_str(path.res.def_id())),
|
||||
hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()),
|
||||
};
|
||||
|
||||
@@ -517,6 +517,7 @@ symbols! {
|
||||
async_fn_track_caller,
|
||||
async_fn_traits,
|
||||
async_for_loop,
|
||||
async_gen_internals,
|
||||
async_iterator,
|
||||
async_iterator_poll_next,
|
||||
async_trait_bounds,
|
||||
|
||||
@@ -1147,7 +1147,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
||||
|
||||
Box::new(segment.into_iter())
|
||||
}
|
||||
hir::QPath::LangItem(_, _) => Box::new(iter::empty()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user