Skip to content

Commit a77bf4b

Browse files
committed
WIP on recursive delegations
1 parent 52fda2e commit a77bf4b

File tree

4 files changed

+76
-25
lines changed

4 files changed

+76
-25
lines changed

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use hir::{BodyId, HirId};
4444
use rustc_abi::ExternAbi;
4545
use rustc_ast::*;
4646
use rustc_attr_parsing::{AttributeParser, ShouldEmit};
47+
use rustc_data_structures::fx::FxHashSet;
4748
use rustc_errors::ErrorGuaranteed;
4849
use rustc_hir::Target;
4950
use rustc_hir::attrs::{AttributeKind, InlineAttr};
@@ -119,10 +120,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
119120
&mut self,
120121
delegation: &Delegation,
121122
item_id: NodeId,
122-
is_in_trait_impl: bool,
123+
_is_in_trait_impl: bool,
123124
) -> DelegationResults<'hir> {
124125
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
125-
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
126+
127+
let sig_id = self.get_resolution_id(
128+
self.resolver
129+
.delegation_resolution_info
130+
.get(&self.local_def_id(item_id))
131+
.unwrap()
132+
.resolution_id,
133+
span,
134+
);
135+
126136
match sig_id {
127137
Ok(sig_id) => {
128138
self.add_attributes_if_needed(span, sig_id);
@@ -236,26 +246,42 @@ impl<'hir> LoweringContext<'_, 'hir> {
236246
}
237247
}
238248

239-
fn get_delegation_sig_id(
240-
&self,
241-
item_id: NodeId,
242-
path_id: NodeId,
243-
span: Span,
244-
is_in_trait_impl: bool,
245-
) -> Result<DefId, ErrorGuaranteed> {
246-
let sig_id = if is_in_trait_impl { item_id } else { path_id };
247-
self.get_resolution_id(sig_id, span)
248-
}
249-
250-
fn get_resolution_id(&self, node_id: NodeId, span: Span) -> Result<DefId, ErrorGuaranteed> {
251-
let def_id =
252-
self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id());
253-
def_id.ok_or_else(|| {
249+
fn get_resolution_id(&self, mut node_id: NodeId, span: Span) -> Result<DefId, ErrorGuaranteed> {
250+
let create_error = |node_id: NodeId| {
254251
self.tcx.dcx().span_delayed_bug(
255252
span,
256253
format!("LoweringContext: couldn't resolve node {:?} in delegation item", node_id),
257254
)
258-
})
255+
};
256+
257+
let mut processed: FxHashSet<NodeId> = Default::default();
258+
259+
loop {
260+
processed.insert(node_id);
261+
262+
let def_id = self
263+
.resolver
264+
.get_partial_res(node_id)
265+
.and_then(|r| r.expect_full_res().opt_def_id());
266+
267+
if let Some(def_id) = def_id
268+
&& let Some(local_id) = def_id.as_local()
269+
&& !self.resolver.delegation_fn_sigs.contains_key(&local_id)
270+
{
271+
if let Some(info) = self.resolver.delegation_resolution_info.get(&local_id) {
272+
node_id = info.resolution_id;
273+
if processed.contains(&node_id) {
274+
return Err(create_error(node_id));
275+
}
276+
277+
continue;
278+
} else {
279+
return Err(create_error(node_id));
280+
}
281+
}
282+
283+
return def_id.ok_or_else(|| create_error(node_id));
284+
}
259285
}
260286

261287
fn lower_delegation_generics(&mut self, span: Span) -> &'hir hir::Generics<'hir> {

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ pub struct ResolverAstLowering {
220220

221221
/// Information about functions signatures for delegation items expansion
222222
pub delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
223+
pub delegation_resolution_info: LocalDefIdMap<DelegationResolutionInfo>,
223224
}
224225

225226
bitflags::bitflags! {
@@ -242,6 +243,11 @@ pub struct DelegationFnSig {
242243
pub to_inherit_attrs: AttrVec,
243244
}
244245

246+
#[derive(Debug)]
247+
pub struct DelegationResolutionInfo {
248+
pub resolution_id: ast::NodeId,
249+
}
250+
245251
#[derive(Clone, Copy, Debug, HashStable)]
246252
pub struct MainDefinition {
247253
pub res: Res<ast::NodeId>,

compiler/rustc_resolve/src/late.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_middle::middle::resolve_bound_vars::Set1;
3131
use rustc_middle::ty::{
3232
AssocTag, DELEGATION_INHERIT_ATTRS_START, DelegationFnSig, DelegationFnSigAttrs, Visibility,
3333
};
34+
use rustc_middle::ty::{AssocTag, DelegationFnSig, DelegationResolutionInfo, Visibility};
3435
use rustc_middle::{bug, span_bug};
3536
use rustc_session::config::{CrateType, ResolveDocLinks};
3637
use rustc_session::lint;
@@ -2928,7 +2929,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
29282929
item.id,
29292930
LifetimeBinderKind::Function,
29302931
span,
2931-
|this| this.resolve_delegation(delegation),
2932+
|this| this.resolve_delegation(delegation, item.id, false),
29322933
);
29332934
}
29342935

@@ -3257,7 +3258,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
32573258
item.id,
32583259
LifetimeBinderKind::Function,
32593260
delegation.path.segments.last().unwrap().ident.span,
3260-
|this| this.resolve_delegation(delegation),
3261+
|this| this.resolve_delegation(delegation, item.id, false),
32613262
);
32623263
}
32633264
AssocItemKind::Type(box TyAlias { generics, .. }) => self
@@ -3550,7 +3551,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
35503551
|i, s, c| MethodNotMemberOfTrait(i, s, c),
35513552
);
35523553

3553-
this.resolve_delegation(delegation)
3554+
this.resolve_delegation(delegation, item.id, trait_id.is_some());
35543555
},
35553556
);
35563557
}
@@ -3699,17 +3700,34 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
36993700
})
37003701
}
37013702

3702-
fn resolve_delegation(&mut self, delegation: &'ast Delegation) {
3703+
fn resolve_delegation(
3704+
&mut self,
3705+
delegation: &'ast Delegation,
3706+
item_id: NodeId,
3707+
is_in_trait_impl: bool,
3708+
) {
37033709
self.smart_resolve_path(
37043710
delegation.id,
37053711
&delegation.qself,
37063712
&delegation.path,
37073713
PathSource::Delegation,
37083714
);
3715+
37093716
if let Some(qself) = &delegation.qself {
37103717
self.visit_ty(&qself.ty);
37113718
}
3719+
37123720
self.visit_path(&delegation.path);
3721+
3722+
if let Some(def_id) = self.r.opt_local_def_id(item_id) {
3723+
self.r.delegation_resolution_info.insert(
3724+
def_id,
3725+
DelegationResolutionInfo {
3726+
resolution_id: if is_in_trait_impl { item_id } else { delegation.id },
3727+
},
3728+
);
3729+
}
3730+
37133731
let Some(body) = &delegation.body else { return };
37143732
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
37153733
let span = delegation.path.segments.last().unwrap().ident.span;
@@ -4294,7 +4312,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
42944312
);
42954313
}
42964314

4297-
#[instrument(level = "debug", skip(self))]
42984315
fn smart_resolve_path_fragment(
42994316
&mut self,
43004317
qself: &Option<Box<QSelf>>,

compiler/rustc_resolve/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ use rustc_middle::middle::privacy::EffectiveVisibilities;
7070
use rustc_middle::query::Providers;
7171
use rustc_middle::span_bug;
7272
use rustc_middle::ty::{
73-
self, DelegationFnSig, Feed, MainDefinition, RegisteredTools, ResolverAstLowering,
74-
ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
73+
self, DelegationFnSig, DelegationResolutionInfo, Feed, MainDefinition, RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility
7574
};
7675
use rustc_query_system::ich::StableHashingContext;
7776
use rustc_session::config::CrateType;
@@ -1276,6 +1275,7 @@ pub struct Resolver<'ra, 'tcx> {
12761275
/// Amount of lifetime parameters for each item in the crate.
12771276
item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
12781277
delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
1278+
delegation_resolution_info: LocalDefIdMap<DelegationResolutionInfo>,
12791279

12801280
main_def: Option<MainDefinition> = None,
12811281
trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
@@ -1694,6 +1694,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16941694
current_crate_outer_attr_insert_span,
16951695
mods_with_parse_errors: Default::default(),
16961696
impl_trait_names: Default::default(),
1697+
delegation_resolution_info: Default::default(),
16971698
..
16981699
};
16991700

@@ -1822,6 +1823,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18221823
lifetime_elision_allowed: self.lifetime_elision_allowed,
18231824
lint_buffer: Steal::new(self.lint_buffer),
18241825
delegation_fn_sigs: self.delegation_fn_sigs,
1826+
delegation_resolution_info: self.delegation_resolution_info
18251827
};
18261828
ResolverOutputs { global_ctxt, ast_lowering }
18271829
}

0 commit comments

Comments
 (0)