Skip to content

Commit 8051485

Browse files
authored
Unrolled build for #150704
Rollup merge of #150704 - Kivooeo:const-ctor, r=BoxyUwU MGCA: Const constructors support part of #132980 fixes #132985 fixes #136138 fixes #139596 r? BoxyUwU
2 parents 4d73a00 + d32f1c6 commit 8051485

File tree

11 files changed

+254
-55
lines changed

11 files changed

+254
-55
lines changed

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs‎

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,9 +1415,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14151415
let ct = self.check_param_uses_if_mcg(ct, span, false);
14161416
Ok(ct)
14171417
}
1418-
TypeRelativePath::Ctor { ctor_def_id, args } => {
1419-
return Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args)));
1420-
}
1418+
TypeRelativePath::Ctor { ctor_def_id, args } => match tcx.def_kind(ctor_def_id) {
1419+
DefKind::Ctor(_, CtorKind::Fn) => {
1420+
Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args)))
1421+
}
1422+
DefKind::Ctor(ctor_of, CtorKind::Const) => {
1423+
Ok(self.construct_const_ctor_value(ctor_def_id, ctor_of, args))
1424+
}
1425+
_ => unreachable!(),
1426+
},
14211427
// FIXME(mgca): implement support for this once ready to support all adt ctor expressions,
14221428
// not just const ctors
14231429
TypeRelativePath::Variant { .. } => {
@@ -1452,7 +1458,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14521458
// FIXME(mgca): do we want constructor resolutions to take priority over
14531459
// other possible resolutions?
14541460
if matches!(mode, LowerTypeRelativePathMode::Const)
1455-
&& let Some((CtorKind::Fn, ctor_def_id)) = variant_def.ctor
1461+
&& let Some((_, ctor_def_id)) = variant_def.ctor
14561462
{
14571463
tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
14581464
let _ = self.prohibit_generic_args(
@@ -2597,14 +2603,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25972603
);
25982604
self.lower_const_param(def_id, hir_id)
25992605
}
2600-
Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
2606+
Res::Def(DefKind::Const, did) => {
26012607
assert_eq!(opt_self_ty, None);
26022608
let [leading_segments @ .., segment] = path.segments else { bug!() };
26032609
let _ = self
26042610
.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
26052611
let args = self.lower_generic_args_of_path_segment(span, did, segment);
26062612
ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
26072613
}
2614+
Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
2615+
assert_eq!(opt_self_ty, None);
2616+
let [leading_segments @ .., segment] = path.segments else { bug!() };
2617+
let _ = self
2618+
.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
2619+
2620+
let parent_did = tcx.parent(did);
2621+
let generics_did = match ctor_of {
2622+
CtorOf::Variant => tcx.parent(parent_did),
2623+
CtorOf::Struct => parent_did,
2624+
};
2625+
let args = self.lower_generic_args_of_path_segment(span, generics_did, segment);
2626+
2627+
self.construct_const_ctor_value(did, ctor_of, args)
2628+
}
26082629
Res::Def(DefKind::Ctor(_, CtorKind::Fn), did) => {
26092630
assert_eq!(opt_self_ty, None);
26102631
let [leading_segments @ .., segment] = path.segments else { bug!() };
@@ -3174,4 +3195,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
31743195
}
31753196
Some(r)
31763197
}
3198+
3199+
fn construct_const_ctor_value(
3200+
&self,
3201+
ctor_def_id: DefId,
3202+
ctor_of: CtorOf,
3203+
args: GenericArgsRef<'tcx>,
3204+
) -> Const<'tcx> {
3205+
let tcx = self.tcx();
3206+
let parent_did = tcx.parent(ctor_def_id);
3207+
3208+
let adt_def = tcx.adt_def(match ctor_of {
3209+
CtorOf::Variant => tcx.parent(parent_did),
3210+
CtorOf::Struct => parent_did,
3211+
});
3212+
3213+
let variant_idx = adt_def.variant_index_with_id(parent_did);
3214+
3215+
let valtree = if adt_def.is_enum() {
3216+
let discr = ty::ValTree::from_scalar_int(tcx, variant_idx.as_u32().into());
3217+
ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, discr, tcx.types.u32)])
3218+
} else {
3219+
ty::ValTree::zst(tcx)
3220+
};
3221+
3222+
let adt_ty = Ty::new_adt(tcx, adt_def, args);
3223+
ty::Const::new_value(tcx, valtree, adt_ty)
3224+
}
31773225
}

‎tests/crashes/132985.rs‎

Lines changed: 0 additions & 17 deletions
This file was deleted.

‎tests/crashes/136138.rs‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎tests/crashes/139596.rs‎

Lines changed: 0 additions & 10 deletions
This file was deleted.

‎tests/crashes/mgca/ace-with-const-ctor.rs‎

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/105952>
2+
3+
#![crate_name = "foo"]
4+
#![feature(min_generic_const_args, adt_const_params)]
5+
#![expect(incomplete_features)]
6+
use std::marker::ConstParamTy;
7+
8+
#[derive(PartialEq, Eq, ConstParamTy)]
9+
pub enum ParseMode {
10+
Raw,
11+
}
12+
pub trait Parse {
13+
#[type_const]
14+
const PARSE_MODE: ParseMode;
15+
}
16+
pub trait RenderRaw {}
17+
18+
//@ hasraw foo/trait.RenderRaw.html 'impl'
19+
//@ hasraw foo/trait.RenderRaw.html 'ParseMode::Raw'
20+
impl<T: Parse<PARSE_MODE = { ParseMode::Raw }>> RenderRaw for T {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![feature(min_generic_const_args, adt_const_params)]
2+
#![expect(incomplete_features)]
3+
use std::marker::ConstParamTy;
4+
5+
#[derive(ConstParamTy, PartialEq, Eq)]
6+
struct U;
7+
8+
#[derive(ConstParamTy, PartialEq, Eq)]
9+
//~^ ERROR overflow evaluating the requirement `S<U> well-formed`
10+
//~| ERROR overflow evaluating the requirement `S<U> well-formed`
11+
12+
struct S<const N: U>()
13+
where
14+
S<{ U }>:;
15+
//~^ ERROR overflow evaluating the requirement `S<U> well-formed`
16+
//~| ERROR overflow evaluating the requirement `S<U> well-formed`
17+
//~| ERROR overflow evaluating the requirement `S<U> well-formed`
18+
19+
fn main() {}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
2+
--> $DIR/const-ctor-overflow-eval.rs:14:5
3+
|
4+
LL | S<{ U }>:;
5+
| ^^^^^^^^
6+
|
7+
note: required by a bound in `S`
8+
--> $DIR/const-ctor-overflow-eval.rs:14:5
9+
|
10+
LL | struct S<const N: U>()
11+
| - required by a bound in this struct
12+
LL | where
13+
LL | S<{ U }>:;
14+
| ^^^^^^^^ required by this bound in `S`
15+
16+
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
17+
--> $DIR/const-ctor-overflow-eval.rs:14:5
18+
|
19+
LL | S<{ U }>:;
20+
| ^^^^^^^^
21+
|
22+
note: required by a bound in `S`
23+
--> $DIR/const-ctor-overflow-eval.rs:14:5
24+
|
25+
LL | struct S<const N: U>()
26+
| - required by a bound in this struct
27+
LL | where
28+
LL | S<{ U }>:;
29+
| ^^^^^^^^ required by this bound in `S`
30+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
31+
32+
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
33+
--> $DIR/const-ctor-overflow-eval.rs:14:5
34+
|
35+
LL | S<{ U }>:;
36+
| ^^^^^^^^
37+
|
38+
note: required by a bound in `S`
39+
--> $DIR/const-ctor-overflow-eval.rs:14:5
40+
|
41+
LL | struct S<const N: U>()
42+
| - required by a bound in this struct
43+
LL | where
44+
LL | S<{ U }>:;
45+
| ^^^^^^^^ required by this bound in `S`
46+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
47+
48+
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
49+
--> $DIR/const-ctor-overflow-eval.rs:8:24
50+
|
51+
LL | #[derive(ConstParamTy, PartialEq, Eq)]
52+
| ^^^^^^^^^
53+
|
54+
note: required by a bound in `S`
55+
--> $DIR/const-ctor-overflow-eval.rs:14:5
56+
|
57+
LL | struct S<const N: U>()
58+
| - required by a bound in this struct
59+
LL | where
60+
LL | S<{ U }>:;
61+
| ^^^^^^^^ required by this bound in `S`
62+
63+
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
64+
--> $DIR/const-ctor-overflow-eval.rs:8:35
65+
|
66+
LL | #[derive(ConstParamTy, PartialEq, Eq)]
67+
| ^^
68+
|
69+
note: required by a bound in `S`
70+
--> $DIR/const-ctor-overflow-eval.rs:14:5
71+
|
72+
LL | struct S<const N: U>()
73+
| - required by a bound in this struct
74+
LL | where
75+
LL | S<{ U }>:;
76+
| ^^^^^^^^ required by this bound in `S`
77+
78+
error: aborting due to 5 previous errors
79+
80+
For more information about this error, try `rustc --explain E0275`.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// to ensure it does not ices like before
2+
3+
#![feature(min_generic_const_args, adt_const_params)]
4+
#![expect(incomplete_features)]
5+
use std::marker::ConstParamTy;
6+
7+
#[derive(ConstParamTy, PartialEq, Eq)]
8+
enum Option<T> {
9+
#[allow(dead_code)]
10+
Some(T),
11+
None,
12+
}
13+
14+
fn pass_enum<const P: Option<u32>>() {}
15+
16+
fn main() {
17+
pass_enum::<{ None }>();
18+
//~^ ERROR missing generics for enum `std::option::Option`
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0107]: missing generics for enum `std::option::Option`
2+
--> $DIR/const-ctor-with-error.rs:17:19
3+
|
4+
LL | pass_enum::<{ None }>();
5+
| ^^^^ expected 1 generic argument
6+
|
7+
help: add missing generic argument
8+
|
9+
LL | pass_enum::<{ None<T> }>();
10+
| +++
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)