Skip to content

Commit b3f7e32

Browse files
committed
Auto merge of rust-lang#157433 - JonathanBrouwer:rollup-d3I87zR, r=JonathanBrouwer
Rollup of 5 pull requests Successful merges: - rust-lang#154586 (Record failed tests with `--record`, and rerun them with `--rerun`) - rust-lang#157296 (delegation: split resolution and lowering) - rust-lang#156171 (Fix a coroutine UI test which is missing `#[coroutine]`) - rust-lang#157249 (tests: codegen-llvm: Update bpf-alu32 with the new LLVM attributes) - rust-lang#157426 (rustc-dev-guide subtree update)
2 parents 9ae765d + 798684a commit b3f7e32

46 files changed

Lines changed: 631 additions & 275 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_ast/src/ast.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,6 +3921,12 @@ pub struct Delegation {
39213921
pub from_glob: bool,
39223922
}
39233923

3924+
impl Delegation {
3925+
pub fn last_segment_span(&self) -> Span {
3926+
self.path.segments.last().unwrap().ident.span
3927+
}
3928+
}
3929+
39243930
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
39253931
pub enum DelegationSuffixes {
39263932
List(ThinVec<(Ident, Option<Ident>)>),

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 96 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,20 @@ use hir::{BodyId, HirId};
4444
use rustc_abi::ExternAbi;
4545
use rustc_ast as ast;
4646
use rustc_ast::*;
47-
use rustc_data_structures::fx::FxHashSet;
48-
use rustc_errors::ErrorGuaranteed;
47+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
4948
use rustc_hir::attrs::{AttributeKind, InlineAttr};
50-
use rustc_hir::def_id::DefId;
49+
use rustc_hir::def_id::{DefId, LocalDefId};
5150
use rustc_hir::{self as hir, FnDeclFlags};
5251
use rustc_middle::span_bug;
53-
use rustc_middle::ty::Asyncness;
52+
use rustc_middle::ty::{Asyncness, TyCtxt};
5453
use rustc_span::symbol::kw;
55-
use rustc_span::{Ident, Span, Symbol};
56-
use smallvec::SmallVec;
54+
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
5755

5856
use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults};
5957
use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee};
6058
use crate::{
6159
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
62-
ResolverAstLoweringExt,
60+
ResolverAstLoweringExt, index_crate,
6361
};
6462

6563
mod generics;
@@ -105,6 +103,66 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
105103
},
106104
];
107105

106+
pub(crate) fn delegations_resolutions(
107+
tcx: TyCtxt<'_>,
108+
_: (),
109+
) -> FxIndexMap<LocalDefId, Result<DefId, ErrorGuaranteed>> {
110+
let krate = tcx.hir_crate(());
111+
112+
let (resolver, ast_crate) = &*krate.delayed_resolver.borrow();
113+
114+
// FIXME!!!(fn_delegation): make ast index lifetime same as resolver,
115+
// as it is too bad to reindex whole crate on each delegation lowering.
116+
let ast_index = index_crate(resolver, ast_crate);
117+
118+
let mut result = FxIndexMap::<LocalDefId, Result<DefId, ErrorGuaranteed>>::default();
119+
120+
for &def_id in &krate.delayed_ids {
121+
let delegation = ast_index[def_id].delegation().expect("processing delegations");
122+
let span = delegation.last_segment_span();
123+
124+
if let Some(info) = resolver.delegation_info(def_id) {
125+
let res = info.resolution_id.map(|id| check_for_cycles(tcx, id, span).map(|_| id));
126+
result.insert(def_id, res.flatten());
127+
} else {
128+
tcx.dcx().span_delayed_bug(
129+
span,
130+
format!("delegation resolution record was not found for {def_id:?}"),
131+
);
132+
}
133+
}
134+
135+
result
136+
}
137+
138+
fn check_for_cycles(tcx: TyCtxt<'_>, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> {
139+
let mut visited: FxHashSet<DefId> = Default::default();
140+
141+
let (resolver, _) = &*tcx.hir_crate(()).delayed_resolver.borrow();
142+
143+
loop {
144+
visited.insert(def_id);
145+
146+
// If def_id is in local crate and it corresponds to another delegation
147+
// it means that we refer to another delegation as a callee, so in order to obtain
148+
// a signature DefId we obtain NodeId of the callee delegation and try to get signature from it.
149+
if let Some(local_id) = def_id.as_local()
150+
&& let Some(info) = resolver.delegation_info(local_id)
151+
&& let Ok(id) = info.resolution_id
152+
{
153+
def_id = id;
154+
if visited.contains(&def_id) {
155+
return Err(match visited.len() {
156+
1 => tcx.dcx().emit_err(UnresolvedDelegationCallee { span }),
157+
_ => tcx.dcx().emit_err(CycleInDelegationSignatureResolution { span }),
158+
});
159+
}
160+
} else {
161+
return Ok(());
162+
}
163+
}
164+
}
165+
108166
impl<'hir> LoweringContext<'_, 'hir> {
109167
fn is_method(&self, def_id: DefId, span: Span) -> bool {
110168
match self.tcx.def_kind(def_id) {
@@ -119,13 +177,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
119177
delegation: &Delegation,
120178
item_id: NodeId,
121179
) -> DelegationResults<'hir> {
122-
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
180+
let span = self.lower_span(delegation.last_segment_span());
123181

124-
// Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356)
125-
let sig_id = if let Some(delegation_info) = self.resolver.delegation_info(self.owner.def_id)
126-
{
127-
self.get_sig_id(delegation_info.resolution_id, span)
128-
} else {
182+
let sig_id = self.tcx.delegations_resolutions(()).get(&self.owner.def_id).copied();
183+
184+
// Delegation can be missing from the `delegations_resolutions` table
185+
// in illegal places such as function bodies in extern blocks (see #151356).
186+
let Some(Ok(sig_id)) = sig_id else {
129187
self.dcx().span_delayed_bug(
130188
span,
131189
format!("LoweringContext: the delegation {:?} is unresolved", item_id),
@@ -134,49 +192,39 @@ impl<'hir> LoweringContext<'_, 'hir> {
134192
return self.generate_delegation_error(span, delegation);
135193
};
136194

137-
match sig_id {
138-
Ok(sig_id) => {
139-
self.add_attrs_if_needed(span, sig_id);
195+
self.add_attrs_if_needed(span, sig_id);
140196

141-
let is_method = self.is_method(sig_id, span);
197+
let is_method = self.is_method(sig_id, span);
142198

143-
let (param_count, c_variadic) = self.param_count(sig_id);
199+
let (param_count, c_variadic) = self.param_count(sig_id);
144200

145-
let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method);
201+
let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method);
146202

147-
let (body_id, call_expr_id) = self.lower_delegation_body(
148-
delegation,
149-
is_method,
150-
param_count,
151-
&mut generics,
152-
span,
153-
);
203+
let (body_id, call_expr_id) =
204+
self.lower_delegation_body(delegation, is_method, param_count, &mut generics, span);
154205

155-
let decl = self.lower_delegation_decl(
156-
sig_id,
157-
param_count,
158-
c_variadic,
159-
span,
160-
&generics,
161-
delegation.id,
162-
call_expr_id,
163-
);
206+
let decl = self.lower_delegation_decl(
207+
sig_id,
208+
param_count,
209+
c_variadic,
210+
span,
211+
&generics,
212+
delegation.id,
213+
call_expr_id,
214+
);
164215

165-
let sig = self.lower_delegation_sig(sig_id, decl, span);
166-
let ident = self.lower_ident(delegation.ident);
216+
let sig = self.lower_delegation_sig(sig_id, decl, span);
217+
let ident = self.lower_ident(delegation.ident);
167218

168-
let generics = self.arena.alloc(hir::Generics {
169-
has_where_clause_predicates: false,
170-
params: self.arena.alloc_from_iter(generics.all_params()),
171-
predicates: self.arena.alloc_from_iter(generics.all_predicates()),
172-
span,
173-
where_clause_span: span,
174-
});
219+
let generics = self.arena.alloc(hir::Generics {
220+
has_where_clause_predicates: false,
221+
params: self.arena.alloc_from_iter(generics.all_params()),
222+
predicates: self.arena.alloc_from_iter(generics.all_predicates()),
223+
span,
224+
where_clause_span: span,
225+
});
175226

176-
DelegationResults { body_id, sig, ident, generics }
177-
}
178-
Err(_) => self.generate_delegation_error(span, delegation),
179-
}
227+
DelegationResults { body_id, sig, ident, generics }
180228
}
181229

182230
fn add_attrs_if_needed(&mut self, span: Span, sig_id: DefId) {
@@ -230,36 +278,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
230278
.collect::<Vec<_>>()
231279
}
232280

233-
fn get_sig_id(&self, mut def_id: DefId, span: Span) -> Result<DefId, ErrorGuaranteed> {
234-
let mut visited: FxHashSet<DefId> = Default::default();
235-
let mut path: SmallVec<[DefId; 1]> = Default::default();
236-
237-
loop {
238-
visited.insert(def_id);
239-
240-
path.push(def_id);
241-
242-
// If def_id is in local crate and it corresponds to another delegation
243-
// it means that we refer to another delegation as a callee, so in order to obtain
244-
// a signature DefId we obtain NodeId of the callee delegation and try to get signature from it.
245-
if let Some(local_id) = def_id.as_local()
246-
&& let Some(delegation_info) = self.resolver.delegation_info(local_id)
247-
{
248-
def_id = delegation_info.resolution_id;
249-
if visited.contains(&def_id) {
250-
// We encountered a cycle in the resolution, or delegation callee refers to non-existent
251-
// entity, in this case emit an error.
252-
return Err(match visited.len() {
253-
1 => self.dcx().emit_err(UnresolvedDelegationCallee { span }),
254-
_ => self.dcx().emit_err(CycleInDelegationSignatureResolution { span }),
255-
});
256-
}
257-
} else {
258-
return Ok(path[0]);
259-
}
260-
}
261-
}
262-
263281
fn get_resolution_id(&self, node_id: NodeId) -> Option<DefId> {
264282
self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id())
265283
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ use rustc_hir::{
6060
use rustc_index::{Idx, IndexSlice, IndexVec};
6161
use rustc_macros::extension;
6262
use rustc_middle::hir::{self as mid_hir};
63+
use rustc_middle::queries::Providers;
6364
use rustc_middle::span_bug;
6465
use rustc_middle::ty::{DelegationInfo, PerOwnerResolverData, ResolverAstLowering, TyCtxt};
6566
use rustc_session::errors::add_feature_diagnostics;
@@ -91,6 +92,12 @@ mod pat;
9192
mod path;
9293
pub mod stability;
9394

95+
pub fn provide(providers: &mut Providers) {
96+
providers.hir_crate = lower_to_hir;
97+
providers.lower_delayed_owner = lower_delayed_owner;
98+
providers.delegations_resolutions = delegation::delegations_resolutions;
99+
}
100+
94101
struct LoweringContext<'a, 'hir> {
95102
tcx: TyCtxt<'hir>,
96103
resolver: &'a ResolverAstLowering<'hir>,
@@ -433,6 +440,16 @@ enum AstOwner<'a> {
433440
ForeignItem(&'a ast::ForeignItem),
434441
}
435442

443+
impl AstOwner<'_> {
444+
fn delegation(&self) -> Option<&ast::Delegation> {
445+
match self {
446+
AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. })
447+
| AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(d), .. }, _) => Some(d),
448+
_ => None,
449+
}
450+
}
451+
}
452+
436453
#[derive(Copy, Clone, Debug)]
437454
enum TryBlockScope {
438455
/// There isn't a `try` block, so a `?` will use `return`.
@@ -512,7 +529,7 @@ fn compute_hir_hash(
512529
})
513530
}
514531

515-
pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
532+
fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
516533
// Queries that borrow `resolver_for_lowering`.
517534
tcx.ensure_done().output_filenames(());
518535
tcx.ensure_done().early_lint_checks(());
@@ -536,13 +553,11 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
536553
let mut delayed_ids: FxIndexSet<LocalDefId> = Default::default();
537554

538555
for def_id in ast_index.indices() {
539-
match &ast_index[def_id] {
540-
AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. })
541-
| AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => {
542-
delayed_ids.insert(def_id);
543-
}
544-
_ => lowerer.lower_node(def_id),
545-
};
556+
if ast_index[def_id].delegation().is_some() {
557+
delayed_ids.insert(def_id);
558+
} else {
559+
lowerer.lower_node(def_id);
560+
}
546561
}
547562

548563
// Don't hash unless necessary, because it's expensive.
@@ -554,7 +569,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
554569
}
555570

556571
/// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way.
557-
pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) {
572+
fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) {
558573
let krate = tcx.hir_crate(());
559574

560575
let (resolver, krate) = &*krate.delayed_resolver.borrow();

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,8 +877,6 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) {
877877
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
878878
let providers = &mut Providers::default();
879879
providers.queries.analysis = analysis;
880-
providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir;
881-
providers.queries.lower_delayed_owner = rustc_ast_lowering::lower_delayed_owner;
882880
// `hir_delayed_owner` is fed during `lower_delayed_owner`, by default it returns phantom,
883881
// as if this query was not fed it means that `MaybeOwner` does not exist for provided LocalDefId.
884882
providers.queries.hir_delayed_owner = |_, _| MaybeOwner::Phantom;
@@ -887,6 +885,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
887885
providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
888886
providers.queries.early_lint_checks = early_lint_checks;
889887
providers.queries.env_var_os = env_var_os;
888+
rustc_ast_lowering::provide(&mut providers.queries);
890889
limits::provide(&mut providers.queries);
891890
proc_macro_decls::provide(&mut providers.queries);
892891
rustc_expand::provide(&mut providers.queries);

compiler/rustc_middle/src/queries.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,12 @@ rustc_queries! {
20692069
desc { "getting delegation user-specified args" }
20702070
}
20712071

2072+
query delegations_resolutions(_: ()) -> &'tcx FxIndexMap<LocalDefId, Result<DefId, ErrorGuaranteed>> {
2073+
arena_cache
2074+
eval_always
2075+
desc { "getting delegations resolutions" }
2076+
}
2077+
20722078
/// Does lifetime resolution on items. Importantly, we can't resolve
20732079
/// lifetimes directly on things like trait methods, because of trait params.
20742080
/// See `rustc_resolve::late::lifetimes` for details.

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ pub struct DelegationInfo {
270270
/// Refers to the next element in a delegation resolution chain.
271271
/// Usually points to the final resolution, as most "chains" are just
272272
/// one step to a trait or an impl.
273-
pub resolution_id: DefId,
273+
pub resolution_id: Result<DefId, ErrorGuaranteed>,
274274
}
275275

276276
#[derive(Clone, Copy, Debug, StableHash)]

compiler/rustc_resolve/src/late.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3899,24 +3899,24 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38993899
this.visit_path(&delegation.path);
39003900
});
39013901

3902-
let resolution_id = if is_in_trait_impl { item_id } else { delegation.id };
3902+
let resolution_node_id = if is_in_trait_impl { item_id } else { delegation.id };
39033903
let def_id = self
39043904
.r
39053905
.partial_res_map
3906-
.get(&resolution_id)
3906+
.get(&resolution_node_id)
39073907
.and_then(|r| r.expect_full_res().opt_def_id());
3908-
if let Some(resolution_id) = def_id {
3909-
self.r
3910-
.delegation_infos
3911-
.insert(self.r.current_owner.def_id, DelegationInfo { resolution_id });
3912-
} else {
3908+
3909+
let resolution_id = def_id.ok_or_else(|| {
39133910
self.r.tcx.dcx().span_delayed_bug(
39143911
delegation.path.span,
39153912
format!(
3916-
"LoweringContext: couldn't resolve node {resolution_id:?} in delegation item",
3913+
"LateResolutionVisitor: couldn't resolve node {resolution_node_id:?} in delegation item",
39173914
),
3918-
);
3919-
};
3915+
)
3916+
});
3917+
3918+
let info = DelegationInfo { resolution_id };
3919+
self.r.delegation_infos.insert(self.r.current_owner.def_id, info);
39203920

39213921
let Some(body) = &delegation.body else { return };
39223922
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {

0 commit comments

Comments
 (0)