Skip to content

Commit a019ac7

Browse files
committed
Lower hir::ConstArgKind::Struct to a ValTree
1 parent c55d8ab commit a019ac7

File tree

1 file changed

+75
-2
lines changed
  • compiler/rustc_hir_analysis/src/hir_ty_lowering

1 file changed

+75
-2
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,8 +2263,81 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22632263
)
22642264
.unwrap_or_else(|guar| Const::new_error(tcx, guar))
22652265
}
2266-
hir::ConstArgKind::Struct(..) => {
2267-
span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg)
2266+
hir::ConstArgKind::Struct(qpath, inits) => {
2267+
let (ty, variant_did) = match qpath {
2268+
hir::QPath::Resolved(maybe_qself, path) => {
2269+
debug!(?maybe_qself, ?path);
2270+
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2271+
let ty = self.lower_resolved_ty_path(
2272+
opt_self_ty,
2273+
path,
2274+
hir_id,
2275+
PermitVariants::Yes,
2276+
);
2277+
let variant_did = match path.res {
2278+
Res::Def(DefKind::Variant | DefKind::Struct, did) => did,
2279+
_ => todo!(),
2280+
};
2281+
2282+
(ty, variant_did)
2283+
}
2284+
hir::QPath::TypeRelative(hir_self_ty, segment) => {
2285+
debug!(?hir_self_ty, ?segment);
2286+
let self_ty = self.lower_ty(hir_self_ty);
2287+
let opt_res = self.lower_type_relative_ty_path(
2288+
self_ty,
2289+
hir_self_ty,
2290+
segment,
2291+
hir_id,
2292+
const_arg.span(),
2293+
PermitVariants::Yes,
2294+
);
2295+
2296+
let (ty, res, res_def_id) = match opt_res {
2297+
Ok(r @ (_, DefKind::Variant | DefKind::Struct, _)) => r,
2298+
Ok(_) => todo!(),
2299+
Err(e) => return ty::Const::new_error(tcx, e),
2300+
};
2301+
2302+
(ty, res_def_id)
2303+
}
2304+
};
2305+
2306+
let (adt_def, adt_args) = match ty.kind() {
2307+
ty::Adt(adt_def, args) => (adt_def, args),
2308+
_ => todo!(),
2309+
};
2310+
2311+
let variant_def = adt_def.variant_with_id(variant_did);
2312+
let variant_idx = adt_def.variant_index_with_id(variant_did).as_u32();
2313+
2314+
let fields = variant_def
2315+
.fields
2316+
.iter()
2317+
.map(|field_def| {
2318+
let init_expr = inits
2319+
.iter()
2320+
.find(|init_expr| init_expr.field.name == field_def.name)
2321+
.unwrap();
2322+
self.lower_const_arg(
2323+
init_expr.expr,
2324+
FeedConstTy::Param(field_def.did, adt_args),
2325+
)
2326+
})
2327+
.collect::<Vec<_>>();
2328+
2329+
let opt_discr_const = if adt_def.is_enum() {
2330+
let valtree = ty::ValTree::from_scalar_int(tcx, variant_idx.into());
2331+
Some(ty::Const::new_value(tcx, valtree, tcx.types.u32))
2332+
} else {
2333+
None
2334+
};
2335+
2336+
let valtree = ty::ValTree::from_ty_const_branches(
2337+
tcx,
2338+
opt_discr_const.into_iter().chain(fields),
2339+
);
2340+
ty::Const::new_value(tcx, valtree, ty)
22682341
}
22692342
hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
22702343
hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),

0 commit comments

Comments
 (0)