Skip to content

Commit 81461f0

Browse files
committed
ast conv for adt ctors and fns
1 parent 89e1009 commit 81461f0

File tree

5 files changed

+73
-28
lines changed

5 files changed

+73
-28
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::borrow::Cow;
33

44
use either::{Left, Right};
55

6-
use rustc_hir::def::DefKind;
6+
use rustc_hir::def::{CtorKind, DefKind};
77
use rustc_middle::mir;
88
use rustc_middle::mir::interpret::ErrorHandled;
99
use rustc_middle::mir::pretty::display_allocation;
@@ -44,6 +44,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
4444
| DefKind::AnonConst
4545
| DefKind::InlineConst
4646
| DefKind::AssocConst
47+
| DefKind::Ctor(_, CtorKind::Const)
4748
),
4849
"Unexpected DefKind: {:?}",
4950
ecx.tcx.def_kind(cid.instance.def_id())

compiler/rustc_hir_analysis/src/astconv/mod.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -3839,8 +3839,44 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
38393839
)
38403840
}
38413841

3842-
DefKind::Ctor(_, _) => todo!(),
3843-
DefKind::Fn => todo!(),
3842+
DefKind::Fn | DefKind::Ctor(_, _) => {
3843+
let path_segs = self.def_ids_for_value_path_segments(
3844+
path.segments,
3845+
None,
3846+
def_kind,
3847+
def_id,
3848+
ast_ct.span(),
3849+
);
3850+
3851+
let generic_segs: FxHashSet<_> =
3852+
path_segs.iter().map(|&PathSeg(_, index)| index).collect();
3853+
self.prohibit_generics(
3854+
path.segments.iter().enumerate().filter_map(|(n, segment)| {
3855+
if generic_segs.contains(&n) { Some(segment) } else { None }
3856+
}),
3857+
|_| {},
3858+
);
3859+
3860+
let seg = path_segs.last().unwrap();
3861+
let arg_segment = &path.segments[seg.1];
3862+
3863+
let substs =
3864+
self.ast_path_substs_for_ty(ast_ct.span(), seg.0, arg_segment);
3865+
3866+
match def_kind {
3867+
DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
3868+
ty::Const::zero_sized(
3869+
tcx,
3870+
tcx.type_of(def_id).subst(tcx, substs),
3871+
)
3872+
}
3873+
DefKind::Ctor(_, CtorKind::Const) => tcx.mk_const(
3874+
UnevaluatedConst { def: def_id, substs },
3875+
tcx.type_of(def_id).subst(tcx, substs),
3876+
),
3877+
_ => unreachable!(),
3878+
}
3879+
}
38443880

38453881
DefKind::AssocFn | DefKind::AssocConst => {
38463882
unimplemented!("multi segment paths are not supported")

compiler/rustc_middle/src/ty/print/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ pub trait PrettyPrinter<'tcx>:
13441344
match ct.kind() {
13451345
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
13461346
match self.tcx().def_kind(def) {
1347-
DefKind::Const | DefKind::AssocConst => {
1347+
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst => {
13481348
p!(print_value_path(def, substs))
13491349
}
13501350
DefKind::AnonConst => {

compiler/rustc_mir_transform/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
215215
}
216216
impl<'tcx> Visitor<'tcx> for GatherCtors<'_> {
217217
fn visit_variant_data(&mut self, v: &'tcx hir::VariantData<'tcx>) {
218-
if let hir::VariantData::Tuple(_, _, def_id) = *v {
218+
if let hir::VariantData::Tuple(_, _, def_id) | hir::VariantData::Unit(_, def_id) = *v {
219219
self.set.insert(def_id);
220220
}
221221
intravisit::walk_struct_def(self, v)

compiler/rustc_mir_transform/src/shim.rs

+31-23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use hir::def::{CtorKind, CtorOf, DefKind};
12
use rustc_hir as hir;
23
use rustc_hir::def_id::DefId;
34
use rustc_hir::lang_items::LangItem;
@@ -834,27 +835,40 @@ fn build_call_shim<'tcx>(
834835
}
835836

836837
pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
837-
debug_assert!(tcx.is_constructor(ctor_id));
838-
839838
let param_env = tcx.param_env_reveal_all_normalized(ctor_id);
839+
let span = tcx.def_span(ctor_id);
840840

841-
// Normalize the sig.
842-
let sig = tcx
843-
.fn_sig(ctor_id)
844-
.subst_identity()
845-
.no_bound_vars()
846-
.expect("LBR in ADT constructor signature");
847-
let sig = tcx.normalize_erasing_regions(param_env, sig);
841+
let (local_decls, inputs, adt_ty) = match tcx.def_kind(ctor_id) {
842+
DefKind::Ctor(_, CtorKind::Fn) => {
843+
// Normalize the sig.
844+
let sig = tcx
845+
.fn_sig(ctor_id)
846+
.subst_identity()
847+
.no_bound_vars()
848+
.expect("LBR in ADT constructor signature");
849+
let sig = tcx.normalize_erasing_regions(param_env, sig);
850+
debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig);
851+
852+
(local_decls_for_sig(&sig, span), sig.inputs().len(), sig.output())
853+
}
854+
DefKind::Ctor(of, CtorKind::Const) => {
855+
let mut ctor_id = ctor_id;
856+
if let CtorOf::Variant = of {
857+
ctor_id = tcx.parent(ctor_id);
858+
}
859+
let adt = tcx.parent(ctor_id);
860+
let adt_ty =
861+
tcx.normalize_erasing_regions(param_env, tcx.type_of(adt).subst_identity());
848862

849-
let ty::Adt(adt_def, substs) = sig.output().kind() else {
850-
bug!("unexpected type for ADT ctor {:?}", sig.output());
863+
let local_decls = std::iter::once(LocalDecl::new(adt_ty, span)).collect();
864+
(local_decls, 0, adt_ty)
865+
}
866+
def_kind => bug!("ctor_id {:?} was expected to be a `DefKind::Ctor`", def_kind),
851867
};
852868

853-
debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig);
854-
855-
let span = tcx.def_span(ctor_id);
856-
857-
let local_decls = local_decls_for_sig(&sig, span);
869+
let ty::Adt(adt_def, substs) = adt_ty.kind() else {
870+
bug!("unexpected type for ADT ctor {:?}", adt_ty);
871+
};
858872

859873
let source_info = SourceInfo::outermost(span);
860874

@@ -891,13 +905,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
891905
};
892906

893907
let source = MirSource::item(ctor_id);
894-
let body = new_body(
895-
source,
896-
IndexVec::from_elem_n(start_block, 1),
897-
local_decls,
898-
sig.inputs().len(),
899-
span,
900-
);
908+
let body = new_body(source, IndexVec::from_elem_n(start_block, 1), local_decls, inputs, span);
901909

902910
crate::pass_manager::dump_mir_for_phase_change(tcx, &body);
903911

0 commit comments

Comments
 (0)