Skip to content

Commit 5c441e6

Browse files
committed
ty-aware delayed AST -> HIR lowering
1 parent fd0c901 commit 5c441e6

21 files changed

Lines changed: 398 additions & 454 deletions

File tree

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 47 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,15 @@ use hir::{BodyId, HirId};
4545
use rustc_abi::ExternAbi;
4646
use rustc_ast as ast;
4747
use rustc_ast::*;
48-
use rustc_attr_parsing::{AttributeParser, ShouldEmit};
4948
use rustc_data_structures::fx::FxHashSet;
5049
use rustc_errors::ErrorGuaranteed;
5150
use rustc_hir as hir;
5251
use rustc_hir::attrs::{AttributeKind, InlineAttr};
53-
use rustc_hir::def_id::{DefId, LocalDefId};
52+
use rustc_hir::def_id::DefId;
5453
use rustc_middle::span_bug;
55-
use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs};
54+
use rustc_middle::ty::Asyncness;
5655
use rustc_span::symbol::kw;
57-
use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
56+
use rustc_span::{Ident, Span, Symbol};
5857
use smallvec::SmallVec;
5958

6059
use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults};
@@ -80,7 +79,7 @@ struct AttrAdditionInfo {
8079

8180
enum AttrAdditionKind {
8281
Default { factory: fn(Span) -> hir::Attribute },
83-
Inherit { flag: DelegationFnSigAttrs, factory: fn(Span, &hir::Attribute) -> hir::Attribute },
82+
Inherit { factory: fn(Span, &hir::Attribute) -> hir::Attribute },
8483
}
8584

8685
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
@@ -97,7 +96,6 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
9796

9897
hir::Attribute::Parsed(AttributeKind::MustUse { span, reason })
9998
},
100-
flag: DelegationFnSigAttrs::MUST_USE,
10199
},
102100
},
103101
AttrAdditionInfo {
@@ -108,43 +106,11 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
108106
},
109107
];
110108

111-
type DelegationIdsVec = SmallVec<[DefId; 1]>;
112-
113-
// As delegations can now refer to another delegation, we have a delegation path
114-
// of the following type: reuse (current delegation) <- reuse (delegee_id) <- ... <- reuse <- function (root_function_id).
115-
// In its most basic and widely used form: reuse (current delegation) <- function (delegee_id, root_function_id)
116-
struct DelegationIds {
117-
path: DelegationIdsVec,
118-
}
119-
120-
impl DelegationIds {
121-
fn new(path: DelegationIdsVec) -> Self {
122-
assert!(!path.is_empty());
123-
Self { path }
124-
}
125-
126-
// Id of the first function in (non)local crate that is being reused
127-
fn root_function_id(&self) -> DefId {
128-
*self.path.last().expect("Ids vector can't be empty")
129-
}
130-
131-
// Id of the first definition which is being reused,
132-
// can be either function, in this case `root_id == delegee_id`, or other delegation
133-
fn delegee_id(&self) -> DefId {
134-
*self.path.first().expect("Ids vector can't be empty")
135-
}
136-
}
137-
138109
impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
139110
fn is_method(&self, def_id: DefId, span: Span) -> bool {
140111
match self.tcx.def_kind(def_id) {
141112
DefKind::Fn => false,
142-
DefKind::AssocFn => match def_id.as_local() {
143-
Some(local_def_id) => {
144-
self.resolver.delegation_fn_sig(local_def_id).is_some_and(|sig| sig.has_self)
145-
}
146-
None => self.tcx.associated_item(def_id).is_method(),
147-
},
113+
DefKind::AssocFn => self.tcx.associated_item(def_id).is_method(),
148114
_ => span_bug!(span, "unexpected DefKind for delegation item"),
149115
}
150116
}
@@ -157,10 +123,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
157123
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
158124

159125
// Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356)
160-
let ids = if let Some(delegation_info) =
126+
let sig_id = if let Some(delegation_info) =
161127
self.resolver.delegation_info(self.local_def_id(item_id))
162128
{
163-
self.get_delegation_ids(delegation_info.resolution_node, span)
129+
self.get_sig_id(delegation_info.resolution_node, span)
164130
} else {
165131
return self.generate_delegation_error(
166132
self.dcx().span_delayed_bug(
@@ -172,28 +138,16 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
172138
);
173139
};
174140

175-
match ids {
176-
Ok(ids) => {
177-
self.add_attrs_if_needed(span, &ids);
178-
179-
let delegee_id = ids.delegee_id();
180-
let root_function_id = ids.root_function_id();
141+
match sig_id {
142+
Ok(sig_id) => {
143+
self.add_attrs_if_needed(span, sig_id);
181144

182-
// `is_method` is used to choose the name of the first parameter (`self` or `arg0`),
183-
// if the original function is not a method (without `self`), then it can not be added
184-
// during chain of reuses, so we use `root_function_id` here
185-
let is_method = self.is_method(root_function_id, span);
145+
let is_method = self.is_method(sig_id, span);
186146

187-
// Here we use `root_function_id` as we can not get params information out of potential delegation reuse,
188-
// we need a function to extract this information
189-
let (param_count, c_variadic) = self.param_count(root_function_id);
147+
let (param_count, c_variadic) = self.param_count(sig_id);
190148

191-
let mut generics = self.lower_delegation_generics(
192-
delegation,
193-
ids.root_function_id(),
194-
item_id,
195-
span,
196-
);
149+
let mut generics =
150+
self.lower_delegation_generics(delegation, sig_id, item_id, span);
197151

198152
let body_id = self.lower_delegation_body(
199153
delegation,
@@ -204,20 +158,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
204158
span,
205159
);
206160

207-
// Here we use `delegee_id`, as this id will then be used to calculate parent for generics
208-
// inheritance, and we want this id to point on a delegee, not on the original
209-
// function (see https://github.com/rust-lang/rust/issues/150152#issuecomment-3674834654)
210-
let decl = self.lower_delegation_decl(
211-
delegee_id,
212-
param_count,
213-
c_variadic,
214-
span,
215-
&generics,
216-
);
161+
let decl =
162+
self.lower_delegation_decl(sig_id, param_count, c_variadic, span, &generics);
217163

218-
// Here we pass `root_function_id` as we want to inherit signature (including consts, async)
219-
// from the root function that started delegation
220-
let sig = self.lower_delegation_sig(root_function_id, decl, span);
164+
let sig = self.lower_delegation_sig(sig_id, decl, span);
221165
let ident = self.lower_ident(delegation.ident);
222166

223167
let generics = self.arena.alloc(hir::Generics {
@@ -236,9 +180,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
236180
}
237181
}
238182

239-
fn add_attrs_if_needed(&mut self, span: Span, ids: &DelegationIds) {
183+
fn add_attrs_if_needed(&mut self, span: Span, sig_id: DefId) {
240184
let new_attrs =
241-
self.create_new_attrs(ATTRS_ADDITIONS, span, ids, self.attrs.get(&PARENT_ID));
185+
self.create_new_attrs(ATTRS_ADDITIONS, span, sig_id, self.attrs.get(&PARENT_ID));
242186

243187
if new_attrs.is_empty() {
244188
return;
@@ -258,15 +202,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
258202
&self,
259203
candidate_additions: &[AttrAdditionInfo],
260204
span: Span,
261-
ids: &DelegationIds,
205+
sig_id: DefId,
262206
existing_attrs: Option<&&[hir::Attribute]>,
263207
) -> Vec<hir::Attribute> {
264-
let defs_orig_attrs = ids
265-
.path
266-
.iter()
267-
.map(|def_id| (*def_id, self.parse_local_original_attrs(*def_id)))
268-
.collect::<Vec<_>>();
269-
270208
candidate_additions
271209
.iter()
272210
.filter_map(|addition_info| {
@@ -280,83 +218,22 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
280218

281219
match addition_info.kind {
282220
AttrAdditionKind::Default { factory } => Some(factory(span)),
283-
AttrAdditionKind::Inherit { flag, factory } => {
284-
for (def_id, orig_attrs) in &defs_orig_attrs {
285-
let original_attr = match def_id.as_local() {
286-
Some(local_id) => self
287-
.get_attrs(local_id)
288-
.flags
289-
.contains(flag)
290-
.then(|| {
291-
orig_attrs
292-
.as_ref()
293-
.map(|attrs| {
294-
attrs.iter().find(|base_attr| {
295-
(addition_info.equals)(base_attr)
296-
})
297-
})
298-
.flatten()
299-
})
300-
.flatten(),
301-
None =>
302-
{
303-
#[allow(deprecated)]
304-
self.tcx
305-
.get_all_attrs(*def_id)
306-
.iter()
307-
.find(|base_attr| (addition_info.equals)(base_attr))
308-
}
309-
};
310-
311-
if let Some(original_attr) = original_attr {
312-
return Some(factory(span, original_attr));
313-
}
314-
}
315-
316-
None
221+
AttrAdditionKind::Inherit { factory, .. } =>
222+
{
223+
#[allow(deprecated)]
224+
self.tcx
225+
.get_all_attrs(sig_id)
226+
.iter()
227+
.find_map(|a| (addition_info.equals)(a).then(|| factory(span, a)))
317228
}
318229
}
319230
})
320231
.collect::<Vec<_>>()
321232
}
322233

323-
fn parse_local_original_attrs(&self, def_id: DefId) -> Option<Vec<hir::Attribute>> {
324-
if let Some(local_id) = def_id.as_local() {
325-
let attrs = &self.get_attrs(local_id).to_inherit;
326-
327-
if !attrs.is_empty() {
328-
return Some(AttributeParser::parse_limited_all(
329-
self.tcx.sess,
330-
attrs,
331-
None,
332-
hir::Target::Fn,
333-
DUMMY_SP,
334-
DUMMY_NODE_ID,
335-
Some(self.tcx.features()),
336-
ShouldEmit::Nothing,
337-
));
338-
}
339-
}
340-
341-
None
342-
}
343-
344-
fn get_attrs(&self, local_id: LocalDefId) -> &DelegationAttrs {
345-
// local_id can correspond either to a function or other delegation
346-
if let Some(fn_sig) = self.resolver.delegation_fn_sig(local_id) {
347-
&fn_sig.attrs
348-
} else {
349-
&self.resolver.delegation_info(local_id).expect("processing delegation").attrs
350-
}
351-
}
352-
353-
fn get_delegation_ids(
354-
&self,
355-
mut node_id: NodeId,
356-
span: Span,
357-
) -> Result<DelegationIds, ErrorGuaranteed> {
234+
fn get_sig_id(&self, mut node_id: NodeId, span: Span) -> Result<DefId, ErrorGuaranteed> {
358235
let mut visited: FxHashSet<NodeId> = Default::default();
359-
let mut path: DelegationIdsVec = Default::default();
236+
let mut path: SmallVec<[DefId; 1]> = Default::default();
360237

361238
loop {
362239
visited.insert(node_id);
@@ -389,7 +266,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
389266
});
390267
}
391268
} else {
392-
return Ok(DelegationIds::new(path));
269+
return Ok(path[0]);
393270
}
394271
}
395272
}
@@ -400,15 +277,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
400277

401278
// Function parameter count, including C variadic `...` if present.
402279
fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) {
403-
if let Some(local_sig_id) = def_id.as_local() {
404-
match self.resolver.delegation_fn_sig(local_sig_id) {
405-
Some(sig) => (sig.param_count, sig.c_variadic),
406-
None => (0, false),
407-
}
408-
} else {
409-
let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();
410-
(sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic)
411-
}
280+
let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();
281+
(sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic)
412282
}
413283

414284
fn lower_delegation_decl(
@@ -455,41 +325,21 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
455325
decl: &'hir hir::FnDecl<'hir>,
456326
span: Span,
457327
) -> hir::FnSig<'hir> {
458-
let header = if let Some(local_sig_id) = sig_id.as_local() {
459-
match self.resolver.delegation_fn_sig(local_sig_id) {
460-
Some(sig) => {
461-
let parent = self.tcx.parent(sig_id);
462-
// HACK: we override the default safety instead of generating attributes from the ether.
463-
// We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
464-
// and here we need the hir attributes.
465-
let default_safety =
466-
if sig.attrs.flags.contains(DelegationFnSigAttrs::TARGET_FEATURE)
467-
|| self.tcx.def_kind(parent) == DefKind::ForeignMod
468-
{
469-
hir::Safety::Unsafe
470-
} else {
471-
hir::Safety::Safe
472-
};
473-
self.lower_fn_header(sig.header, default_safety, &[])
474-
}
475-
None => self.generate_header_error(),
476-
}
477-
} else {
478-
let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
479-
let asyncness = match self.tcx.asyncness(sig_id) {
480-
Asyncness::Yes => hir::IsAsync::Async(span),
481-
Asyncness::No => hir::IsAsync::NotAsync,
482-
};
483-
hir::FnHeader {
484-
safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features {
485-
hir::HeaderSafety::SafeTargetFeatures
486-
} else {
487-
hir::HeaderSafety::Normal(sig.safety)
488-
},
489-
constness: self.tcx.constness(sig_id),
490-
asyncness,
491-
abi: sig.abi,
492-
}
328+
let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
329+
let asyncness = match self.tcx.asyncness(sig_id) {
330+
Asyncness::Yes => hir::IsAsync::Async(span),
331+
Asyncness::No => hir::IsAsync::NotAsync,
332+
};
333+
334+
let header = hir::FnHeader {
335+
safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features {
336+
hir::HeaderSafety::SafeTargetFeatures
337+
} else {
338+
hir::HeaderSafety::Normal(sig.safety)
339+
},
340+
constness: self.tcx.constness(sig_id),
341+
asyncness,
342+
abi: sig.abi,
493343
};
494344

495345
hir::FnSig { decl, header, span }

0 commit comments

Comments
 (0)