Skip to content

Commit 7cbff63

Browse files
committed
Remove QPath::LangItem from ranges
1 parent 9c98533 commit 7cbff63

33 files changed

+158
-218
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14841484
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
14851485
let e1 = self.lower_expr_mut(e1);
14861486
let e2 = self.lower_expr_mut(e2);
1487-
let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, span);
1487+
let fn_path = self.make_lang_item_qpath(hir::LangItem::RangeInclusiveNew, span, None);
14881488
let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path)));
14891489
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
14901490
}
@@ -1570,7 +1570,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15701570
);
15711571

15721572
hir::ExprKind::Struct(
1573-
self.arena.alloc(hir::QPath::LangItem(lang_item, span)),
1573+
self.arena.alloc(self.make_lang_item_qpath(lang_item, span, None)),
15741574
fields,
15751575
hir::StructTailExpr::None,
15761576
)

compiler/rustc_hir/src/hir.rs

Lines changed: 35 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ use rustc_index::IndexVec;
2323
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
2424
use rustc_span::def_id::LocalDefId;
2525
use rustc_span::source_map::Spanned;
26-
use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
26+
use rustc_span::{
27+
BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Symbol, kw, sym,
28+
};
2729
use rustc_target::asm::InlineAsmRegOrRegClass;
2830
use smallvec::SmallVec;
2931
use thin_vec::ThinVec;
@@ -2600,102 +2602,21 @@ impl Expr<'_> {
26002602
) => path1.res == path2.res,
26012603
(
26022604
ExprKind::Struct(
2603-
QPath::LangItem(LangItem::RangeTo, _),
2604-
[val1],
2605-
StructTailExpr::None,
2606-
),
2607-
ExprKind::Struct(
2608-
QPath::LangItem(LangItem::RangeTo, _),
2609-
[val2],
2610-
StructTailExpr::None,
2611-
),
2612-
)
2613-
| (
2614-
ExprKind::Struct(
2615-
QPath::LangItem(LangItem::RangeToInclusive, _),
2616-
[val1],
2617-
StructTailExpr::None,
2618-
),
2619-
ExprKind::Struct(
2620-
QPath::LangItem(LangItem::RangeToInclusive, _),
2621-
[val2],
2622-
StructTailExpr::None,
2623-
),
2624-
)
2625-
| (
2626-
ExprKind::Struct(
2627-
QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
2628-
[val1],
2629-
StructTailExpr::None,
2630-
),
2631-
ExprKind::Struct(
2632-
QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
2633-
[val2],
2634-
StructTailExpr::None,
2635-
),
2636-
)
2637-
| (
2638-
ExprKind::Struct(
2639-
QPath::LangItem(LangItem::RangeFrom, _),
2640-
[val1],
2641-
StructTailExpr::None,
2642-
),
2643-
ExprKind::Struct(
2644-
QPath::LangItem(LangItem::RangeFrom, _),
2645-
[val2],
2646-
StructTailExpr::None,
2647-
),
2648-
)
2649-
| (
2650-
ExprKind::Struct(
2651-
QPath::LangItem(LangItem::RangeFromCopy, _),
2652-
[val1],
2605+
&QPath::Resolved(None, &Path { res: Res::Def(_, path1_def_id), .. }),
2606+
args1,
26532607
StructTailExpr::None,
26542608
),
26552609
ExprKind::Struct(
2656-
QPath::LangItem(LangItem::RangeFromCopy, _),
2657-
[val2],
2658-
StructTailExpr::None,
2659-
),
2660-
) => val1.expr.equivalent_for_indexing(val2.expr),
2661-
(
2662-
ExprKind::Struct(
2663-
QPath::LangItem(LangItem::Range, _),
2664-
[val1, val3],
2665-
StructTailExpr::None,
2666-
),
2667-
ExprKind::Struct(
2668-
QPath::LangItem(LangItem::Range, _),
2669-
[val2, val4],
2670-
StructTailExpr::None,
2671-
),
2672-
)
2673-
| (
2674-
ExprKind::Struct(
2675-
QPath::LangItem(LangItem::RangeCopy, _),
2676-
[val1, val3],
2677-
StructTailExpr::None,
2678-
),
2679-
ExprKind::Struct(
2680-
QPath::LangItem(LangItem::RangeCopy, _),
2681-
[val2, val4],
2682-
StructTailExpr::None,
2683-
),
2684-
)
2685-
| (
2686-
ExprKind::Struct(
2687-
QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2688-
[val1, val3],
2689-
StructTailExpr::None,
2690-
),
2691-
ExprKind::Struct(
2692-
QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2693-
[val2, val4],
2610+
&QPath::Resolved(None, &Path { res: Res::Def(_, path2_def_id), .. }),
2611+
args2,
26942612
StructTailExpr::None,
26952613
),
26962614
) => {
2697-
val1.expr.equivalent_for_indexing(val2.expr)
2698-
&& val3.expr.equivalent_for_indexing(val4.expr)
2615+
path2_def_id == path1_def_id
2616+
&& is_range_literal(self)
2617+
&& is_range_literal(other)
2618+
&& std::iter::zip(args1, args2)
2619+
.all(|(a, b)| a.expr.equivalent_for_indexing(b.expr))
26992620
}
27002621
_ => false,
27012622
}
@@ -2713,30 +2634,29 @@ impl Expr<'_> {
27132634
/// Checks if the specified expression is a built-in range literal.
27142635
/// (See: `LoweringContext::lower_expr()`).
27152636
pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2716-
match expr.kind {
2717-
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
2718-
ExprKind::Struct(ref qpath, _, _) => matches!(
2719-
**qpath,
2720-
QPath::LangItem(
2721-
LangItem::Range
2722-
| LangItem::RangeTo
2723-
| LangItem::RangeFrom
2724-
| LangItem::RangeFull
2725-
| LangItem::RangeToInclusive
2726-
| LangItem::RangeCopy
2727-
| LangItem::RangeFromCopy
2728-
| LangItem::RangeInclusiveCopy
2729-
| LangItem::RangeToInclusiveCopy,
2730-
..
2731-
)
2732-
),
2733-
2734-
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
2735-
ExprKind::Call(ref func, _) => {
2736-
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
2737-
}
2738-
2739-
_ => false,
2637+
if let ExprKind::Struct(QPath::Resolved(None, path), _, StructTailExpr::None) = expr.kind
2638+
&& let [.., segment] = path.segments
2639+
&& let sym::RangeFrom
2640+
| sym::RangeFull
2641+
| sym::Range
2642+
| sym::RangeToInclusive
2643+
| sym::RangeTo
2644+
| sym::RangeFromCopy
2645+
| sym::RangeCopy
2646+
| sym::RangeInclusiveCopy
2647+
| sym::RangeToInclusiveCopy = segment.ident.name
2648+
&& expr.span.is_desugaring(DesugaringKind::RangeExpr)
2649+
{
2650+
true
2651+
} else if let ExprKind::Call(func, _) = &expr.kind
2652+
&& let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
2653+
&& let [.., segment] = path.segments
2654+
&& let sym::range_inclusive_new = segment.ident.name
2655+
&& expr.span.is_desugaring(DesugaringKind::RangeExpr)
2656+
{
2657+
true
2658+
} else {
2659+
false
27402660
}
27412661
}
27422662

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_hir::attrs::AttributeKind;
1919
use rustc_hir::def::{CtorKind, DefKind, Res};
2020
use rustc_hir::def_id::DefId;
2121
use rustc_hir::lang_items::LangItem;
22-
use rustc_hir::{ExprKind, HirId, QPath, find_attr};
22+
use rustc_hir::{ExprKind, HirId, QPath, find_attr, is_range_literal};
2323
use rustc_hir_analysis::NoVariantNamed;
2424
use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _};
2525
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin};
@@ -2506,9 +2506,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25062506
args: GenericArgsRef<'tcx>,
25072507
mut err: Diag<'_>,
25082508
) {
2509-
// I don't use 'is_range_literal' because only double-sided, half-open ranges count.
2510-
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [range_start, range_end], _) =
2511-
last_expr_field.expr.kind
2509+
if is_range_literal(last_expr_field.expr)
2510+
&& let ExprKind::Struct(&qpath, [range_start, range_end], _) = last_expr_field.expr.kind
2511+
&& self.tcx.qpath_is_lang_item(qpath, LangItem::Range)
25122512
&& let variant_field =
25132513
variant.fields.iter().find(|field| field.ident(self.tcx) == last_expr_field.ident)
25142514
&& let range_def_id = self.tcx.lang_items().range_struct()

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,8 +1032,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10321032
// inherent impl, we need to record the
10331033
// `T` for posterity (see `UserSelfTy` for
10341034
// details).
1035-
let self_ty = self_ty.expect("UFCS sugared assoc missing Self").raw;
1036-
user_self_ty = Some(UserSelfTy { impl_def_id: container_id, self_ty });
1035+
// Generated desugaring code may have a path without a self.
1036+
user_self_ty = self_ty.map(|self_ty| UserSelfTy {
1037+
impl_def_id: container_id,
1038+
self_ty: self_ty.raw,
1039+
});
10371040
}
10381041
}
10391042
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, lis
88
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
99
use rustc_hir::def_id::DefId;
1010
use rustc_hir::intravisit::Visitor;
11-
use rustc_hir::{Expr, ExprKind, HirId, LangItem, Node, QPath};
11+
use rustc_hir::{Expr, ExprKind, HirId, LangItem, Node, QPath, is_range_literal};
1212
use rustc_hir_analysis::check::potentially_plural_count;
1313
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, PermitVariants};
1414
use rustc_index::IndexVec;
@@ -2052,8 +2052,9 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> {
20522052
fn detect_dotdot(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, expr: &hir::Expr<'tcx>) {
20532053
if let ty::Adt(adt, _) = ty.kind()
20542054
&& self.tcx().is_lang_item(adt.did(), hir::LangItem::RangeFull)
2055-
&& let hir::ExprKind::Struct(hir::QPath::LangItem(hir::LangItem::RangeFull, _), [], _) =
2056-
expr.kind
2055+
&& is_range_literal(expr)
2056+
&& let hir::ExprKind::Struct(&path, [], _) = expr.kind
2057+
&& self.tcx().qpath_is_lang_item(path, hir::LangItem::RangeFull)
20572058
{
20582059
// We have `Foo(a, .., c)`, where the user might be trying to use the "rest" syntax
20592060
// from default field values, which is not supported on tuples.

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::{
1212
self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind,
1313
GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind,
14-
WherePredicateKind, expr_needs_parens,
14+
WherePredicateKind, expr_needs_parens, is_range_literal,
1515
};
1616
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
1717
use rustc_hir_analysis::suggest_impl_trait;
@@ -1664,7 +1664,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16641664
return false;
16651665
}
16661666
match expr.kind {
1667-
ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, end], _) => {
1667+
ExprKind::Struct(&qpath, [start, end], _)
1668+
if is_range_literal(expr)
1669+
&& self.tcx.qpath_is_lang_item(qpath, LangItem::Range) =>
1670+
{
16681671
err.span_suggestion_verbose(
16691672
start.expr.span.shrink_to_hi().with_hi(end.expr.span.lo()),
16701673
"remove the unnecessary `.` operator for a floating point literal",
@@ -1673,24 +1676,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16731676
);
16741677
true
16751678
}
1676-
ExprKind::Struct(QPath::LangItem(LangItem::RangeFrom, ..), [start], _) => {
1677-
let range_span = expr.span.parent_callsite().unwrap();
1678-
err.span_suggestion_verbose(
1679-
range_span.with_lo(start.expr.span.hi()),
1680-
"remove the unnecessary `.` operator for a floating point literal",
1681-
'.',
1682-
Applicability::MaybeIncorrect,
1683-
);
1684-
true
1685-
}
1686-
ExprKind::Struct(QPath::LangItem(LangItem::RangeTo, ..), [end], _) => {
1679+
ExprKind::Struct(&qpath, [arg], _)
1680+
if is_range_literal(expr)
1681+
&& let Some(qpath @ (LangItem::RangeFrom | LangItem::RangeTo)) =
1682+
self.tcx.qpath_lang_item(qpath) =>
1683+
{
16871684
let range_span = expr.span.parent_callsite().unwrap();
1688-
err.span_suggestion_verbose(
1689-
range_span.until(end.expr.span),
1690-
"remove the unnecessary `.` operator and add an integer part for a floating point literal",
1691-
"0.",
1692-
Applicability::MaybeIncorrect,
1693-
);
1685+
match qpath {
1686+
LangItem::RangeFrom => {
1687+
err.span_suggestion_verbose(
1688+
range_span.with_lo(arg.expr.span.hi()),
1689+
"remove the unnecessary `.` operator for a floating point literal",
1690+
'.',
1691+
Applicability::MaybeIncorrect,
1692+
);
1693+
}
1694+
_ => {
1695+
err.span_suggestion_verbose(
1696+
range_span.until(arg.expr.span),
1697+
"remove the unnecessary `.` operator and add an integer part for a floating point literal",
1698+
"0.",
1699+
Applicability::MaybeIncorrect,
1700+
);
1701+
}
1702+
}
16941703
true
16951704
}
16961705
ExprKind::Lit(Spanned {
@@ -3497,11 +3506,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34973506
if !hir::is_range_literal(expr) {
34983507
return;
34993508
}
3500-
let hir::ExprKind::Struct(hir::QPath::LangItem(LangItem::Range, ..), [start, end], _) =
3501-
expr.kind
3502-
else {
3509+
let hir::ExprKind::Struct(&qpath, [start, end], _) = expr.kind else {
35033510
return;
35043511
};
3512+
if !self.tcx.qpath_is_lang_item(qpath, LangItem::Range) {
3513+
return;
3514+
}
35053515
if let hir::Node::ExprField(_) = self.tcx.parent_hir_node(expr.hir_id) {
35063516
// Ignore `Foo { field: a..Default::default() }`
35073517
return;

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
1919
use rustc_hir::def_id::DefId;
2020
use rustc_hir::intravisit::{self, Visitor};
2121
use rustc_hir::lang_items::LangItem;
22-
use rustc_hir::{self as hir, ExprKind, HirId, Node, PathSegment, QPath, find_attr};
22+
use rustc_hir::{
23+
self as hir, ExprKind, HirId, Node, PathSegment, QPath, find_attr, is_range_literal,
24+
};
2325
use rustc_infer::infer::{BoundRegionConversionTime, RegionVariableOrigin};
2426
use rustc_middle::bug;
2527
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
@@ -2412,22 +2414,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24122414
if let SelfSource::MethodCall(expr) = source {
24132415
for (_, parent) in tcx.hir_parent_iter(expr.hir_id).take(5) {
24142416
if let Node::Expr(parent_expr) = parent {
2417+
if !is_range_literal(parent_expr) {
2418+
continue;
2419+
}
24152420
let lang_item = match parent_expr.kind {
2416-
ExprKind::Struct(qpath, _, _) => match *qpath {
2417-
QPath::LangItem(LangItem::Range, ..) => Some(LangItem::Range),
2418-
QPath::LangItem(LangItem::RangeCopy, ..) => Some(LangItem::RangeCopy),
2419-
QPath::LangItem(LangItem::RangeInclusiveCopy, ..) => {
2420-
Some(LangItem::RangeInclusiveCopy)
2421-
}
2422-
QPath::LangItem(LangItem::RangeTo, ..) => Some(LangItem::RangeTo),
2423-
QPath::LangItem(LangItem::RangeToInclusive, ..) => {
2424-
Some(LangItem::RangeToInclusive)
2425-
}
2421+
ExprKind::Struct(qpath, _, _) => match tcx.qpath_lang_item(*qpath) {
2422+
Some(
2423+
lang_item @ (LangItem::Range
2424+
| LangItem::RangeCopy
2425+
| LangItem::RangeInclusiveCopy
2426+
| LangItem::RangeTo
2427+
| LangItem::RangeToInclusive),
2428+
) => Some(lang_item),
24262429
_ => None,
24272430
},
24282431
ExprKind::Call(func, _) => match func.kind {
24292432
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
2430-
ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)) => {
2433+
ExprKind::Path(qpath)
2434+
if tcx.qpath_is_lang_item(qpath, LangItem::RangeInclusiveNew) =>
2435+
{
24312436
Some(LangItem::RangeInclusiveStruct)
24322437
}
24332438
_ => None,

src/tools/clippy/clippy_lints/src/indexing_slicing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
124124
let note = "the suggestion might not be applicable in constant blocks";
125125
let ty = cx.typeck_results().expr_ty(array).peel_refs();
126126
let allowed_in_tests = self.allow_indexing_slicing_in_tests && is_in_test(cx.tcx, expr.hir_id);
127-
if let Some(range) = higher::Range::hir(index) {
127+
if let Some(range) = higher::Range::hir(cx, index) {
128128
// Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
129129
if let ty::Array(_, s) = ty.kind() {
130130
let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {

0 commit comments

Comments
 (0)