Skip to content

Commit 58b5e22

Browse files
committed
Factor out QPath::LangItem
1 parent 5438f58 commit 58b5e22

File tree

34 files changed

+260
-329
lines changed

34 files changed

+260
-329
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 40 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
3030

3131
pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
3232
ensure_sufficient_stack(|| {
33+
let mut span = None;
3334
let kind = match e.kind {
3435
ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)),
3536
ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
@@ -210,10 +211,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
210211
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er))
211212
}
212213
ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
213-
self.lower_expr_range_closed(e.span, e1, e2)
214+
let (kind, s) = self.lower_expr_range_closed(e.span, e1, e2);
215+
span = Some(s);
216+
kind
214217
}
215218
ExprKind::Range(ref e1, ref e2, lims) => {
216-
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
219+
let (kind, s) =
220+
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims);
221+
span = Some(s);
222+
kind
217223
}
218224
ExprKind::Underscore => {
219225
self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
@@ -303,7 +309,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
303309

304310
let hir_id = self.lower_node_id(e.id);
305311
self.lower_attrs(hir_id, &e.attrs);
306-
hir::Expr { hir_id, kind, span: self.lower_span(e.span) }
312+
let span = span.unwrap_or_else(|| self.lower_span(e.span));
313+
hir::Expr { hir_id, kind, span }
307314
})
308315
}
309316

@@ -529,12 +536,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
529536
expr: &'hir hir::Expr<'hir>,
530537
overall_span: Span,
531538
) -> &'hir hir::Expr<'hir> {
532-
let constructor = self.arena.alloc(self.expr_lang_item_path(
533-
method_span,
534-
lang_item,
535-
AttrVec::new(),
536-
None,
537-
));
539+
let constructor = self.expr_lang_item_path(method_span, lang_item);
538540
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
539541
}
540542

@@ -652,15 +654,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
652654
// `future::from_generator`:
653655
let unstable_span =
654656
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
655-
let gen_future = self.expr_lang_item_path(
656-
unstable_span,
657-
hir::LangItem::FromGenerator,
658-
AttrVec::new(),
659-
None,
660-
);
657+
let gen_future = self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator);
661658

662659
// `future::from_generator(generator)`:
663-
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
660+
hir::ExprKind::Call(gen_future, arena_vec![self; generator])
664661
}
665662

666663
/// Desugar `<expr>.await` into:
@@ -726,19 +723,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
726723
span,
727724
hir::LangItem::PinNewUnchecked,
728725
arena_vec![self; ref_mut_awaitee],
729-
Some(expr_hir_id),
730726
);
731727
let get_context = self.expr_call_lang_item_fn_mut(
732728
gen_future_span,
733729
hir::LangItem::GetContext,
734730
arena_vec![self; task_context],
735-
Some(expr_hir_id),
736731
);
737732
let call = self.expr_call_lang_item_fn(
738733
span,
739734
hir::LangItem::FuturePoll,
740735
arena_vec![self; new_unchecked, get_context],
741-
Some(expr_hir_id),
742736
);
743737
self.arena.alloc(self.expr_unsafe(call))
744738
};
@@ -751,12 +745,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
751745
let (x_pat, x_pat_hid) = self.pat_ident(gen_future_span, x_ident);
752746
let x_expr = self.expr_ident(gen_future_span, x_ident, x_pat_hid);
753747
let ready_field = self.single_pat_field(gen_future_span, x_pat);
754-
let ready_pat = self.pat_lang_item_variant(
755-
span,
756-
hir::LangItem::PollReady,
757-
ready_field,
758-
Some(expr_hir_id),
759-
);
748+
let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
760749
let break_x = self.with_loop_scope(loop_node_id, move |this| {
761750
let expr_break =
762751
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
@@ -767,12 +756,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
767756

768757
// `::std::task::Poll::Pending => {}`
769758
let pending_arm = {
770-
let pending_pat = self.pat_lang_item_variant(
771-
span,
772-
hir::LangItem::PollPending,
773-
&[],
774-
Some(expr_hir_id),
775-
);
759+
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
776760
let empty_block = self.expr_block_empty(span);
777761
self.arm(pending_pat, empty_block)
778762
};
@@ -839,7 +823,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
839823
into_future_span,
840824
hir::LangItem::IntoFutureIntoFuture,
841825
arena_vec![self; expr],
842-
Some(expr_hir_id),
843826
);
844827

845828
// match <into_future_expr> {
@@ -1269,14 +1252,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
12691252
}
12701253

12711254
/// Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`.
1272-
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
1255+
fn lower_expr_range_closed(
1256+
&mut self,
1257+
span: Span,
1258+
e1: &Expr,
1259+
e2: &Expr,
1260+
) -> (hir::ExprKind<'hir>, Span) {
12731261
let e1 = self.lower_expr_mut(e1);
12741262
let e2 = self.lower_expr_mut(e2);
1275-
let fn_path =
1276-
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
1277-
let fn_expr =
1278-
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
1279-
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
1263+
let span =
1264+
self.mark_span_with_reason(DesugaringKind::RangeLiteral, self.lower_span(span), None);
1265+
let fn_expr = self.expr_lang_item_path(span, hir::LangItem::RangeInclusiveNew);
1266+
let kind = hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]);
1267+
(kind, span)
12801268
}
12811269

12821270
fn lower_expr_range(
@@ -1285,7 +1273,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12851273
e1: Option<&Expr>,
12861274
e2: Option<&Expr>,
12871275
lims: RangeLimits,
1288-
) -> hir::ExprKind<'hir> {
1276+
) -> (hir::ExprKind<'hir>, Span) {
12891277
use rustc_ast::RangeLimits::*;
12901278

12911279
let lang_item = match (e1, e2, lims) {
@@ -1308,17 +1296,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
13081296
e1.iter().map(|e| (sym::start, e)).chain(e2.iter().map(|e| (sym::end, e))).map(
13091297
|(s, e)| {
13101298
let expr = self.lower_expr(&e);
1311-
let ident = Ident::new(s, self.lower_span(e.span));
1299+
let ident_span =
1300+
self.mark_span_with_reason(DesugaringKind::RangeLiteral, expr.span, None);
1301+
let ident = Ident::new(s, ident_span);
13121302
self.expr_field(ident, expr, e.span)
13131303
},
13141304
),
13151305
);
13161306

1317-
hir::ExprKind::Struct(
1318-
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span), None)),
1319-
fields,
1320-
None,
1321-
)
1307+
let span =
1308+
self.mark_span_with_reason(DesugaringKind::RangeLiteral, self.lower_span(span), None);
1309+
let qpath = self.lang_item_qpath(lang_item, span);
1310+
(hir::ExprKind::Struct(self.arena.alloc(qpath), fields, None), span)
13221311
}
13231312

13241313
fn lower_label(&self, opt_label: Option<Label>) -> Option<Label> {
@@ -1474,7 +1463,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
14741463
head_span,
14751464
hir::LangItem::IteratorNext,
14761465
arena_vec![self; ref_mut_iter],
1477-
None,
14781466
);
14791467
let arms = arena_vec![self; none_arm, some_arm];
14801468

@@ -1503,7 +1491,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
15031491
head_span,
15041492
hir::LangItem::IntoIterIntoIter,
15051493
arena_vec![self; head],
1506-
None,
15071494
)
15081495
};
15091496

@@ -1557,7 +1544,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
15571544
unstable_span,
15581545
hir::LangItem::TryTraitBranch,
15591546
arena_vec![self; sub_expr],
1560-
None,
15611547
)
15621548
};
15631549

@@ -1751,10 +1737,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
17511737
span: Span,
17521738
lang_item: hir::LangItem,
17531739
args: &'hir [hir::Expr<'hir>],
1754-
hir_id: Option<hir::HirId>,
17551740
) -> hir::Expr<'hir> {
1756-
let path =
1757-
self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
1741+
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item));
17581742
self.expr_call_mut(span, path, args)
17591743
}
17601744

@@ -1763,23 +1747,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
17631747
span: Span,
17641748
lang_item: hir::LangItem,
17651749
args: &'hir [hir::Expr<'hir>],
1766-
hir_id: Option<hir::HirId>,
17671750
) -> &'hir hir::Expr<'hir> {
1768-
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args, hir_id))
1751+
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args))
17691752
}
17701753

17711754
fn expr_lang_item_path(
17721755
&mut self,
17731756
span: Span,
17741757
lang_item: hir::LangItem,
1775-
attrs: AttrVec,
1776-
hir_id: Option<hir::HirId>,
1777-
) -> hir::Expr<'hir> {
1778-
self.expr(
1779-
span,
1780-
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
1781-
attrs,
1782-
)
1758+
) -> &'hir hir::Expr<'hir> {
1759+
let qpath = self.lang_item_qpath(lang_item, span);
1760+
let kind = hir::ExprKind::Path(qpath);
1761+
self.arena.alloc(self.expr(span, kind, AttrVec::new()))
17831762
}
17841763

17851764
pub(super) fn expr_ident(

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use rustc_hir as hir;
5959
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
6060
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
6161
use rustc_hir::definitions::DefPathData;
62-
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
62+
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, Target, TraitCandidate};
6363
use rustc_index::vec::{Idx, IndexVec};
6464
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
6565
use rustc_middle::{bug, span_bug};
@@ -71,6 +71,7 @@ use rustc_span::{Span, DUMMY_SP};
7171

7272
use smallvec::SmallVec;
7373
use std::collections::hash_map::Entry;
74+
use std::iter;
7475

7576
macro_rules! arena_vec {
7677
($this:expr; $($x:expr),*) => (
@@ -800,6 +801,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
800801
Ident::new(ident.name, self.lower_span(ident.span))
801802
}
802803

804+
fn lang_item_qpath(&mut self, lang_item: hir::LangItem, span: Span) -> hir::QPath<'hir> {
805+
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
806+
let res = Res::Def(lang_item.target().to_def_kind(), def_id);
807+
let name = self.tcx.item_name(def_id);
808+
let span = self.lower_span(span);
809+
let self_segment =
810+
matches!(lang_item.target(), Target::Method(_) | Target::AssocConst | Target::AssocTy)
811+
.then(|| {
812+
// associated items require a self segment - this works well enough
813+
hir::PathSegment::new(Ident::empty(), self.next_id(), Res::Err)
814+
});
815+
let segment = hir::PathSegment::new(Ident::new(name, span), self.next_id(), res);
816+
let segments =
817+
self.arena.alloc_from_iter(self_segment.into_iter().chain(iter::once(segment)));
818+
let path = self.arena.alloc(hir::Path { span, res, segments });
819+
hir::QPath::Resolved(None, path)
820+
}
821+
803822
/// Converts a lifetime into a new generic parameter.
804823
#[instrument(level = "debug", skip(self))]
805824
fn lifetime_res_to_generic_param(
@@ -2423,21 +2442,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24232442

24242443
fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
24252444
let field = self.single_pat_field(span, pat);
2426-
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
2445+
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
24272446
}
24282447

24292448
fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
24302449
let field = self.single_pat_field(span, pat);
2431-
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
2450+
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
24322451
}
24332452

24342453
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
24352454
let field = self.single_pat_field(span, pat);
2436-
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
2455+
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
24372456
}
24382457

24392458
fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2440-
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
2459+
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
24412460
}
24422461

24432462
fn single_pat_field(
@@ -2460,9 +2479,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24602479
span: Span,
24612480
lang_item: hir::LangItem,
24622481
fields: &'hir [hir::PatField<'hir>],
2463-
hir_id: Option<hir::HirId>,
24642482
) -> &'hir hir::Pat<'hir> {
2465-
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
2483+
let qpath = self.lang_item_qpath(lang_item, span);
24662484
self.pat(span, hir::PatKind::Struct(qpath, fields, false))
24672485
}
24682486

0 commit comments

Comments
 (0)