Skip to content

Commit e289f27

Browse files
committed
Remove QPath::LangItem from for loops
1 parent 7e51a76 commit e289f27

File tree

7 files changed

+54
-29
lines changed

7 files changed

+54
-29
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,7 +1804,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18041804
ForLoopKind::For => {
18051805
// `Iterator::next(&mut iter)`
18061806
let ref_mut_iter = self.expr_mut_addr_of(head_span, iter);
1807-
self.expr_call_lang_item_qpath_fn(
1807+
self.expr_call_lang_item_fn(
18081808
head_span,
18091809
hir::LangItem::IteratorNext,
18101810
arena_vec![self; ref_mut_iter],
@@ -1819,7 +1819,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18191819
// `&mut iter`
18201820
let iter = self.expr_mut_addr_of(head_span, iter);
18211821
// `Pin::new_unchecked(...)`
1822-
let iter = self.arena.alloc(self.expr_call_lang_item_qpath_fn_mut(
1822+
let iter = self.arena.alloc(self.expr_call_lang_item_fn_mut(
18231823
head_span,
18241824
hir::LangItem::PinNewUnchecked,
18251825
arena_vec![self; iter],
@@ -1854,7 +1854,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18541854
let match_expr = match loop_kind {
18551855
ForLoopKind::For => {
18561856
// `::std::iter::IntoIterator::into_iter(<head>)`
1857-
let into_iter_expr = self.expr_call_lang_item_qpath_fn(
1857+
let into_iter_expr = self.expr_call_lang_item_fn(
18581858
head_span,
18591859
hir::LangItem::IntoIterIntoIter,
18601860
arena_vec![self; head],
@@ -1874,7 +1874,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18741874
self.pat_ident_binding_mode(head_span, iter_ident, hir::BindingMode::REF_MUT);
18751875
let iter = self.expr_ident_mut(head_span, iter_ident, async_iter_pat_id);
18761876
// `Pin::new_unchecked(...)`
1877-
let iter = self.arena.alloc(self.expr_call_lang_item_qpath_fn_mut(
1877+
let iter = self.arena.alloc(self.expr_call_lang_item_fn_mut(
18781878
head_span,
18791879
hir::LangItem::PinNewUnchecked,
18801880
arena_vec![self; iter],
@@ -1889,7 +1889,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18891889
));
18901890

18911891
// `::core::async_iter::IntoAsyncIterator::into_async_iter(<head>)`
1892-
let iter = self.expr_call_lang_item_qpath_fn(
1892+
let iter = self.expr_call_lang_item_fn(
18931893
head_span,
18941894
hir::LangItem::IntoAsyncIterIntoIter,
18951895
arena_vec![self; head],

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
23122312
let typeck_results = tcx.typeck(self.mir_def_id());
23132313

23142314
struct ExprFinder<'hir> {
2315+
tcx: TyCtxt<'hir>,
23152316
issue_span: Span,
23162317
expr_span: Span,
23172318
body_expr: Option<&'hir hir::Expr<'hir>>,
@@ -2336,9 +2337,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
23362337
// };
23372338
// corresponding to the desugaring of a for loop `for <pat> in <head> { <body> }`.
23382339
if let hir::ExprKind::Call(path, [arg]) = ex.kind
2339-
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
2340-
path.kind
2340+
&& let hir::ExprKind::Path(qpath) = path.kind
2341+
&& self.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)
23412342
&& arg.span.contains(self.issue_span)
2343+
&& ex.span.desugaring_kind() == Some(DesugaringKind::ForLoop)
23422344
{
23432345
// Find `IntoIterator::into_iter(<head>)`
23442346
self.head = Some(arg);
@@ -2355,10 +2357,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
23552357
..
23562358
}) = stmt.kind
23572359
&& let hir::ExprKind::Call(path, _args) = call.kind
2358-
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IteratorNext, _)) =
2359-
path.kind
2360-
&& let hir::PatKind::Struct(path, [field, ..], _) = bind.pat.kind
2361-
&& let hir::QPath::LangItem(LangItem::OptionSome, pat_span) = path
2360+
&& let hir::ExprKind::Path(qpath) = path.kind
2361+
&& self.tcx.qpath_is_lang_item(qpath, LangItem::IteratorNext)
2362+
&& let hir::PatKind::Struct(qpath, [field, ..], _) = bind.pat.kind
2363+
&& self.tcx.qpath_is_lang_item(qpath, LangItem::OptionSome)
23622364
&& call.span.contains(self.issue_span)
23632365
{
23642366
// Find `<pat>` and the span for the whole `for` loop.
@@ -2370,7 +2372,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
23702372
self.loop_bind = Some(ident);
23712373
}
23722374
self.head_span = Some(*head_span);
2373-
self.pat_span = Some(pat_span);
2375+
self.pat_span = Some(bind.pat.span);
23742376
self.loop_span = Some(stmt.span);
23752377
}
23762378

@@ -2385,6 +2387,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
23852387
}
23862388
}
23872389
let mut finder = ExprFinder {
2390+
tcx,
23882391
expr_span: span,
23892392
issue_span,
23902393
loop_bind: None,

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
763763
call_expr_and_args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
764764
) -> Ty<'tcx> {
765765
let tcx = self.tcx;
766+
767+
if let Some((_, [_arg])) = call_expr_and_args
768+
&& let QPath::Resolved(_, path) = qpath
769+
&& let Res::Def(_, def_id) = path.res
770+
&& let Some(lang_item) = tcx.lang_items().from_def_id(def_id)
771+
{
772+
let code = match lang_item {
773+
LangItem::IntoIterIntoIter | LangItem::IteratorNext
774+
if expr.span.is_desugaring(DesugaringKind::ForLoop) =>
775+
{
776+
Some(ObligationCauseCode::ForLoopIterator)
777+
}
778+
_ => None,
779+
};
780+
if let Some(code) = code {
781+
let args = self.fresh_args_for_item(expr.span, def_id);
782+
self.add_required_obligations_with_code(expr.span, def_id, args, |_, _| {
783+
code.clone()
784+
});
785+
return tcx.type_of(def_id).instantiate(tcx, args);
786+
}
787+
}
788+
766789
let (res, opt_ty, segs) =
767790
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
768791
let ty = match res {

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -721,9 +721,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721721
None
722722
}
723723
}
724-
hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
725-
Some(ObligationCauseCode::ForLoopIterator)
726-
}
727724
hir::LangItem::TryTraitFromOutput
728725
| hir::LangItem::TryTraitFromResidual
729726
| hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark),
@@ -1374,7 +1371,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13741371
}
13751372

13761373
#[instrument(level = "debug", skip(self, code, span, args))]
1377-
fn add_required_obligations_with_code(
1374+
pub(crate) fn add_required_obligations_with_code(
13781375
&self,
13791376
span: Span,
13801377
def_id: DefId,

compiler/rustc_lint/src/shadowed_into_iter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter {
132132
&& let hir::ExprKind::Match(arg, [_], hir::MatchSource::ForLoopDesugar) =
133133
&parent_expr.kind
134134
&& let hir::ExprKind::Call(path, [_]) = &arg.kind
135-
&& let hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoIterIntoIter, ..)) =
136-
&path.kind
135+
&& let hir::ExprKind::Path(qpath) = path.kind
136+
&& cx.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)
137137
{
138138
Some(ShadowedIntoIterDiagSub::RemoveIntoIter {
139139
span: receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),

src/tools/clippy/clippy_lints/src/ranges.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_config::Conf;
22
use clippy_utils::consts::{ConstEvalCtxt, Constant};
33
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
44
use clippy_utils::msrvs::{self, Msrv};
5-
use clippy_utils::res::{MaybeQPath, MaybeResPath};
5+
use clippy_utils::res::MaybeResPath;
66
use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
77
use clippy_utils::sugg::Sugg;
88
use clippy_utils::ty::implements_trait;
@@ -15,7 +15,7 @@ use rustc_lint::{LateContext, LateLintPass, Lint};
1515
use rustc_middle::ty::{self, ClauseKind, GenericArgKind, PredicatePolarity, Ty};
1616
use rustc_session::impl_lint_pass;
1717
use rustc_span::source_map::Spanned;
18-
use rustc_span::{Span, sym};
18+
use rustc_span::{DesugaringKind, Span, sym};
1919
use std::cmp::Ordering;
2020

2121
declare_clippy_lint! {
@@ -368,7 +368,9 @@ fn can_switch_ranges<'tcx>(
368368
// Check if `expr` is the argument of a compiler-generated `IntoIter::into_iter(expr)`
369369
if let ExprKind::Call(func, [arg]) = parent_expr.kind
370370
&& arg.hir_id == use_ctxt.child_id
371-
&& func.opt_lang_path() == Some(LangItem::IntoIterIntoIter)
371+
&& let ExprKind::Path(qpath) = func.kind
372+
&& cx.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)
373+
&& parent_expr.span.is_desugaring(DesugaringKind::ForLoop)
372374
{
373375
return true;
374376
}

tests/ui/unpretty/exhaustive.hir.stdout

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,25 +167,25 @@ mod expressions {
167167
let x;
168168
{
169169
let _t =
170-
match #[lang = "into_iter"](x) {
170+
match into_iter(x) {
171171
mut iter =>
172172
loop {
173-
match #[lang = "next"](&mut iter) {
174-
#[lang = "None"] {} => break,
175-
#[lang = "Some"] { 0: _ } => { }
173+
match next(&mut iter) {
174+
None {} => break,
175+
Some { 0: _ } => { }
176176
}
177177
},
178178
};
179179
_t
180180
};
181181
{
182182
let _t =
183-
match #[lang = "into_iter"](x) {
183+
match into_iter(x) {
184184
mut iter =>
185185
'a: loop {
186-
match #[lang = "next"](&mut iter) {
187-
#[lang = "None"] {} => break,
188-
#[lang = "Some"] { 0: _ } => { }
186+
match next(&mut iter) {
187+
None {} => break,
188+
Some { 0: _ } => { }
189189
}
190190
},
191191
};

0 commit comments

Comments
 (0)