Skip to content

Commit 53aea53

Browse files
committed
Recurse through const items in instance resolution
1 parent b243753 commit 53aea53

File tree

4 files changed

+49
-21
lines changed

4 files changed

+49
-21
lines changed

compiler/rustc_middle/src/mir/consts.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -362,22 +362,7 @@ impl<'tcx> Const<'tcx> {
362362
}
363363
Const::Unevaluated(uneval, _) => {
364364
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
365-
let uneval_ty_ct = ty::Const::new_unevaluated(
366-
tcx,
367-
ty::UnevaluatedConst::new(uneval.def, uneval.args),
368-
);
369-
let mir_ct = tcx.normalize_erasing_regions(typing_env, uneval_ty_ct);
370-
// FIXME: duplicated with above match arm
371-
match mir_ct.kind() {
372-
ConstKind::Value(cv) => Ok(tcx.valtree_to_const_val(cv)),
373-
ConstKind::Expr(_) => {
374-
bug!("Normalization of `ty::ConstKind::Expr` is unimplemented")
375-
}
376-
_ => Err(ReportedErrorInfo::non_const_eval_error(
377-
tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body"),
378-
)
379-
.into()),
380-
}
365+
tcx.const_eval_resolve(typing_env, uneval, span)
381366
}
382367
Const::Val(val, _) => Ok(val),
383368
}

compiler/rustc_middle/src/mir/interpret/queries.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,30 @@ impl<'tcx> TyCtxt<'tcx> {
7575
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
7676
match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
7777
Ok(Some(instance)) => {
78+
if let ty::InstanceKind::Item(def_id) = instance.def
79+
&& matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst)
80+
{
81+
let ct = self.const_of_item(def_id).instantiate(self, instance.args);
82+
match ct.kind() {
83+
ty::ConstKind::Unevaluated(_) => {
84+
return Err(ErrorHandled::TooGeneric(DUMMY_SP));
85+
}
86+
ty::ConstKind::Value(cv) => return Ok(self.valtree_to_const_val(cv)),
87+
ty::ConstKind::Error(guar) => {
88+
return Err(ErrorHandled::Reported(
89+
ReportedErrorInfo::const_eval_error(guar),
90+
DUMMY_SP,
91+
));
92+
}
93+
ty::ConstKind::Expr(_) => return Err(ErrorHandled::TooGeneric(DUMMY_SP)),
94+
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) => {
95+
return Err(ErrorHandled::TooGeneric(DUMMY_SP));
96+
}
97+
ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) => {
98+
bug!("unexpected constant {ct:?}")
99+
}
100+
}
101+
}
78102
let cid = GlobalId { instance, promoted: ct.promoted };
79103
self.const_eval_global_id(typing_env, cid, span)
80104
}

compiler/rustc_resolve/src/def_collector.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
176176
}
177177
// HACK(mgca): see lower_const_item in ast_lowering
178178
ItemKind::Const(box ConstItem { body_id: Some(body_id), .. }) => {
179-
this.create_def(body_id, None, DefKind::InlineConst, i.span);
179+
this.create_def(body_id, None, DefKind::AnonConst, i.span);
180180
}
181181
_ => {}
182182
}
@@ -341,7 +341,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
341341
self.with_parent(def, |this| {
342342
// HACK(mgca): see lower_const_item in ast_lowering
343343
if let AssocItemKind::Const(box ConstItem { body_id: Some(body_id), .. }) = i.kind {
344-
this.create_def(body_id, None, DefKind::InlineConst, i.span);
344+
this.create_def(body_id, None, DefKind::AnonConst, i.span);
345345
}
346346
visit::walk_assoc_item(this, i, ctxt)
347347
});

compiler/rustc_ty_utils/src/instance.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_errors::ErrorGuaranteed;
22
use rustc_hir::LangItem;
3+
use rustc_hir::def::DefKind;
34
use rustc_hir::def_id::DefId;
45
use rustc_infer::infer::TyCtxtInferExt;
56
use rustc_middle::bug;
@@ -10,11 +11,12 @@ use rustc_middle::ty::{
1011
};
1112
use rustc_span::sym;
1213
use rustc_trait_selection::traits;
13-
use tracing::debug;
14+
use tracing::{debug, instrument};
1415
use traits::translate_args;
1516

1617
use crate::errors::UnexpectedFnPtrAssociatedItem;
1718

19+
#[instrument(level = "debug", skip(tcx), ret)]
1820
fn resolve_instance_raw<'tcx>(
1921
tcx: TyCtxt<'tcx>,
2022
key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>,
@@ -90,13 +92,30 @@ fn resolve_instance_raw<'tcx>(
9092
let ty = args.type_at(0);
9193
ty::InstanceKind::AsyncDropGlue(def_id, ty)
9294
} else {
93-
debug!(" => free item");
95+
debug!(" => free or inherent item");
9496
ty::InstanceKind::Item(def_id)
9597
};
9698

9799
Ok(Some(Instance { def, args }))
98100
};
99-
debug!("resolve_instance: result={:?}", result);
101+
if let Ok(Some(Instance { def: ty::InstanceKind::Item(def_id), args })) = result
102+
&& matches!(tcx.def_kind(def_id), DefKind::Const | DefKind::AssocConst)
103+
{
104+
debug!(" => resolved to const item");
105+
let ct = tcx.const_of_item(def_id).instantiate(tcx, args);
106+
debug!("ct={ct:?}");
107+
if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
108+
if tcx.def_kind(uv.def) == DefKind::AnonConst {
109+
return Ok(Some(ty::Instance {
110+
def: ty::InstanceKind::Item(uv.def),
111+
args: uv.args,
112+
}));
113+
} else {
114+
let input = PseudoCanonicalInput { typing_env, value: (uv.def, uv.args) };
115+
return tcx.resolve_instance_raw(input);
116+
}
117+
}
118+
}
100119
result
101120
}
102121

0 commit comments

Comments
 (0)