Skip to content

Commit 1117bd9

Browse files
Rollup merge of #150411 - Kivooeo:somefunnystuff, r=BoxyUwU
refactor `destructure_const` r? BoxyUwU as you suggested yesterday (will add more context like links when it stops being a draft) tried to split this into some meaningful commits hope it help ^^
2 parents 13633c5 + b29cc98 commit 1117bd9

File tree

11 files changed

+171
-156
lines changed

11 files changed

+171
-156
lines changed

‎compiler/rustc_middle/src/mir/pretty.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,8 @@ fn pretty_print_const_value_tcx<'tcx>(
18961896
// Aggregates, printed as array/tuple/struct/variant construction syntax.
18971897
//
18981898
// NB: the `has_non_region_param` check ensures that we can use
1899-
// the `destructure_const` query with an empty `ty::ParamEnv` without
1899+
// the `try_destructure_mir_constant_for_user_output ` query with
1900+
// an empty `TypingEnv::fully_monomorphized` without
19001901
// introducing ICEs (e.g. via `layout_of`) from missing bounds.
19011902
// E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
19021903
// to be able to destructure the tuple into `(0u8, *mut T)`

‎compiler/rustc_middle/src/query/erase.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ tcx_lifetime! {
402402
rustc_middle::ty::ClauseKind,
403403
rustc_middle::ty::ClosureTypeInfo,
404404
rustc_middle::ty::Const,
405-
rustc_middle::ty::DestructuredConst,
405+
rustc_middle::ty::DestructuredAdtConst,
406406
rustc_middle::ty::ExistentialTraitRef,
407407
rustc_middle::ty::FnSig,
408408
rustc_middle::ty::GenericArg,

‎compiler/rustc_middle/src/query/mod.rs‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,12 +1408,6 @@ rustc_queries! {
14081408
desc { "converting type-level constant value to MIR constant value"}
14091409
}
14101410

1411-
/// Destructures array, ADT or tuple constants into the constants
1412-
/// of their fields.
1413-
query destructure_const(key: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> {
1414-
desc { "destructuring type level constant"}
1415-
}
1416-
14171411
// FIXME get rid of this with valtrees
14181412
query lit_to_const(
14191413
key: LitToConstInput<'tcx>

‎compiler/rustc_middle/src/ty/consts/valtree.rs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::fmt;
22
use std::ops::Deref;
33

4+
use rustc_abi::{FIRST_VARIANT, VariantIdx};
45
use rustc_data_structures::intern::Interned;
56
use rustc_hir::def::Namespace;
67
use rustc_macros::{
@@ -189,6 +190,26 @@ impl<'tcx> Value<'tcx> {
189190
ValTreeKind::Leaf(_) => None,
190191
}
191192
}
193+
194+
/// Destructures array, ADT or tuple constants into the constants
195+
/// of their fields.
196+
pub fn destructure_adt_const(&self) -> ty::DestructuredAdtConst<'tcx> {
197+
let fields = self.to_branch();
198+
199+
let (variant, fields) = match self.ty.kind() {
200+
ty::Adt(def, _) if def.variants().is_empty() => {
201+
bug!("unreachable")
202+
}
203+
ty::Adt(def, _) if def.is_enum() => {
204+
let (head, rest) = fields.split_first().unwrap();
205+
(VariantIdx::from_u32(head.to_leaf().to_u32()), rest)
206+
}
207+
ty::Adt(_, _) => (FIRST_VARIANT, fields),
208+
_ => bug!("destructure_adt_const called on non-ADT type: {:?}", self.ty),
209+
};
210+
211+
ty::DestructuredAdtConst { variant, fields }
212+
}
192213
}
193214

194215
impl<'tcx> rustc_type_ir::inherent::ValueConst<TyCtxt<'tcx>> for Value<'tcx> {

‎compiler/rustc_middle/src/ty/mod.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,8 +2331,8 @@ impl<'tcx> fmt::Debug for SymbolName<'tcx> {
23312331

23322332
/// The constituent parts of a type level constant of kind ADT or array.
23332333
#[derive(Copy, Clone, Debug, HashStable)]
2334-
pub struct DestructuredConst<'tcx> {
2335-
pub variant: Option<VariantIdx>,
2334+
pub struct DestructuredAdtConst<'tcx> {
2335+
pub variant: VariantIdx,
23362336
pub fields: &'tcx [ty::Const<'tcx>],
23372337
}
23382338

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

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,66 +1919,65 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
19191919
self.pretty_print_byte_str(bytes)?;
19201920
return Ok(());
19211921
}
1922-
// Aggregates, printed as array/tuple/struct/variant construction syntax.
1923-
(ty::ValTreeKind::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => {
1924-
let contents = self.tcx().destructure_const(ty::Const::new_value(
1925-
self.tcx(),
1926-
cv.valtree,
1927-
cv.ty,
1928-
));
1929-
let fields = contents.fields.iter().copied();
1922+
(ty::ValTreeKind::Branch(fields), ty::Array(..) | ty::Tuple(..)) => {
1923+
let fields_iter = fields.iter().copied();
1924+
19301925
match *cv.ty.kind() {
19311926
ty::Array(..) => {
19321927
write!(self, "[")?;
1933-
self.comma_sep(fields)?;
1928+
self.comma_sep(fields_iter)?;
19341929
write!(self, "]")?;
19351930
}
19361931
ty::Tuple(..) => {
19371932
write!(self, "(")?;
1938-
self.comma_sep(fields)?;
1939-
if contents.fields.len() == 1 {
1933+
self.comma_sep(fields_iter)?;
1934+
if fields.len() == 1 {
19401935
write!(self, ",")?;
19411936
}
19421937
write!(self, ")")?;
19431938
}
1944-
ty::Adt(def, _) if def.variants().is_empty() => {
1945-
self.typed_value(
1946-
|this| {
1947-
write!(this, "unreachable()")?;
1948-
Ok(())
1949-
},
1950-
|this| this.print_type(cv.ty),
1951-
": ",
1952-
)?;
1953-
}
1954-
ty::Adt(def, args) => {
1955-
let variant_idx =
1956-
contents.variant.expect("destructed const of adt without variant idx");
1957-
let variant_def = &def.variant(variant_idx);
1958-
self.pretty_print_value_path(variant_def.def_id, args)?;
1959-
match variant_def.ctor_kind() {
1960-
Some(CtorKind::Const) => {}
1961-
Some(CtorKind::Fn) => {
1962-
write!(self, "(")?;
1963-
self.comma_sep(fields)?;
1964-
write!(self, ")")?;
1965-
}
1966-
None => {
1967-
write!(self, " {{ ")?;
1968-
let mut first = true;
1969-
for (field_def, field) in iter::zip(&variant_def.fields, fields) {
1970-
if !first {
1971-
write!(self, ", ")?;
1972-
}
1973-
write!(self, "{}: ", field_def.name)?;
1974-
field.print(self)?;
1975-
first = false;
1939+
_ => unreachable!(),
1940+
}
1941+
return Ok(());
1942+
}
1943+
(ty::ValTreeKind::Branch(_), ty::Adt(def, args)) => {
1944+
let contents = cv.destructure_adt_const();
1945+
let fields = contents.fields.iter().copied();
1946+
1947+
if def.variants().is_empty() {
1948+
self.typed_value(
1949+
|this| {
1950+
write!(this, "unreachable()")?;
1951+
Ok(())
1952+
},
1953+
|this| this.print_type(cv.ty),
1954+
": ",
1955+
)?;
1956+
} else {
1957+
let variant_idx = contents.variant;
1958+
let variant_def = &def.variant(variant_idx);
1959+
self.pretty_print_value_path(variant_def.def_id, args)?;
1960+
match variant_def.ctor_kind() {
1961+
Some(CtorKind::Const) => {}
1962+
Some(CtorKind::Fn) => {
1963+
write!(self, "(")?;
1964+
self.comma_sep(fields)?;
1965+
write!(self, ")")?;
1966+
}
1967+
None => {
1968+
write!(self, " {{ ")?;
1969+
let mut first = true;
1970+
for (field_def, field) in iter::zip(&variant_def.fields, fields) {
1971+
if !first {
1972+
write!(self, ", ")?;
19761973
}
1977-
write!(self, " }}")?;
1974+
write!(self, "{}: ", field_def.name)?;
1975+
field.print(self)?;
1976+
first = false;
19781977
}
1978+
write!(self, " }}")?;
19791979
}
19801980
}
1981-
_ => unreachable!(),
19821981
}
19831982
return Ok(());
19841983
}

‎compiler/rustc_symbol_mangling/src/v0.rs‎

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -755,9 +755,8 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> {
755755
dereferenced_const.print(self)?;
756756
}
757757

758-
ty::Array(..) | ty::Tuple(..) | ty::Adt(..) | ty::Slice(_) => {
759-
let contents = self.tcx.destructure_const(ct);
760-
let fields = contents.fields.iter().copied();
758+
ty::Array(..) | ty::Tuple(..) | ty::Slice(_) => {
759+
let fields = cv.to_branch().iter().copied();
761760

762761
let print_field_list = |this: &mut Self| {
763762
for field in fields.clone() {
@@ -776,43 +775,51 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> {
776775
self.push("T");
777776
print_field_list(self)?;
778777
}
779-
ty::Adt(def, args) => {
780-
let variant_idx =
781-
contents.variant.expect("destructed const of adt without variant idx");
782-
let variant_def = &def.variant(variant_idx);
778+
_ => unreachable!(),
779+
}
780+
}
781+
ty::Adt(def, args) => {
782+
let contents = cv.destructure_adt_const();
783+
let fields = contents.fields.iter().copied();
784+
785+
let print_field_list = |this: &mut Self| {
786+
for field in fields.clone() {
787+
field.print(this)?;
788+
}
789+
this.push("E");
790+
Ok(())
791+
};
783792

784-
self.push("V");
785-
self.print_def_path(variant_def.def_id, args)?;
793+
let variant_idx = contents.variant;
794+
let variant_def = &def.variant(variant_idx);
786795

787-
match variant_def.ctor_kind() {
788-
Some(CtorKind::Const) => {
789-
self.push("U");
790-
}
791-
Some(CtorKind::Fn) => {
792-
self.push("T");
793-
print_field_list(self)?;
794-
}
795-
None => {
796-
self.push("S");
797-
for (field_def, field) in iter::zip(&variant_def.fields, fields) {
798-
// HACK(eddyb) this mimics `print_path_with_simple`,
799-
// instead of simply using `field_def.ident`,
800-
// just to be able to handle disambiguators.
801-
let disambiguated_field =
802-
self.tcx.def_key(field_def.did).disambiguated_data;
803-
let field_name = disambiguated_field.data.get_opt_name();
804-
self.push_disambiguator(
805-
disambiguated_field.disambiguator as u64,
806-
);
807-
self.push_ident(field_name.unwrap().as_str());
808-
809-
field.print(self)?;
810-
}
811-
self.push("E");
812-
}
796+
self.push("V");
797+
self.print_def_path(variant_def.def_id, args)?;
798+
799+
match variant_def.ctor_kind() {
800+
Some(CtorKind::Const) => {
801+
self.push("U");
802+
}
803+
Some(CtorKind::Fn) => {
804+
self.push("T");
805+
print_field_list(self)?;
806+
}
807+
None => {
808+
self.push("S");
809+
for (field_def, field) in iter::zip(&variant_def.fields, fields) {
810+
// HACK(eddyb) this mimics `print_path_with_simple`,
811+
// instead of simply using `field_def.ident`,
812+
// just to be able to handle disambiguators.
813+
let disambiguated_field =
814+
self.tcx.def_key(field_def.did).disambiguated_data;
815+
let field_name = disambiguated_field.data.get_opt_name();
816+
self.push_disambiguator(disambiguated_field.disambiguator as u64);
817+
self.push_ident(field_name.unwrap().as_str());
818+
819+
field.print(self)?;
813820
}
821+
self.push("E");
814822
}
815-
_ => unreachable!(),
816823
}
817824
}
818825
_ => {

‎compiler/rustc_ty_utils/src/consts.rs‎

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use std::iter;
2-
3-
use rustc_abi::{FIRST_VARIANT, VariantIdx};
41
use rustc_errors::ErrorGuaranteed;
52
use rustc_hir::def::DefKind;
63
use rustc_hir::def_id::LocalDefId;
@@ -10,63 +7,12 @@ use rustc_middle::thir::visit;
107
use rustc_middle::thir::visit::Visitor;
118
use rustc_middle::ty::abstract_const::CastKind;
129
use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitableExt};
13-
use rustc_middle::{bug, mir, thir};
10+
use rustc_middle::{mir, thir};
1411
use rustc_span::Span;
15-
use tracing::{debug, instrument};
12+
use tracing::instrument;
1613

1714
use crate::errors::{GenericConstantTooComplex, GenericConstantTooComplexSub};
1815

19-
/// Destructures array, ADT or tuple constants into the constants
20-
/// of their fields.
21-
fn destructure_const<'tcx>(
22-
tcx: TyCtxt<'tcx>,
23-
const_: ty::Const<'tcx>,
24-
) -> ty::DestructuredConst<'tcx> {
25-
let ty::ConstKind::Value(cv) = const_.kind() else {
26-
bug!("cannot destructure constant {:?}", const_)
27-
};
28-
let branches = cv.to_branch();
29-
30-
let (fields, variant) = match cv.ty.kind() {
31-
ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
32-
// construct the consts for the elements of the array/slice
33-
let field_consts = branches
34-
.iter()
35-
.map(|b| ty::Const::new_value(tcx, b.to_value().valtree, *inner_ty))
36-
.collect::<Vec<_>>();
37-
debug!(?field_consts);
38-
39-
(field_consts, None)
40-
}
41-
ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"),
42-
ty::Adt(def, _) => {
43-
let (variant_idx, field_consts) = if def.is_enum() {
44-
let (head, rest) = branches.split_first().unwrap();
45-
(VariantIdx::from_u32(head.to_leaf().to_u32()), rest)
46-
} else {
47-
(FIRST_VARIANT, branches)
48-
};
49-
debug!(?field_consts);
50-
51-
(field_consts.to_vec(), Some(variant_idx))
52-
}
53-
ty::Tuple(elem_tys) => {
54-
let fields = iter::zip(*elem_tys, branches)
55-
.map(|(elem_ty, elem_valtree)| {
56-
ty::Const::new_value(tcx, elem_valtree.to_value().valtree, elem_ty)
57-
})
58-
.collect::<Vec<_>>();
59-
60-
(fields, None)
61-
}
62-
_ => bug!("cannot destructure constant {:?}", const_),
63-
};
64-
65-
let fields = tcx.arena.alloc_from_iter(fields);
66-
67-
ty::DestructuredConst { variant, fields }
68-
}
69-
7016
/// We do not allow all binary operations in abstract consts, so filter disallowed ones.
7117
fn check_binop(op: mir::BinOp) -> bool {
7218
use mir::BinOp::*;
@@ -432,5 +378,5 @@ fn thir_abstract_const<'tcx>(
432378
}
433379

434380
pub(crate) fn provide(providers: &mut Providers) {
435-
*providers = Providers { destructure_const, thir_abstract_const, ..*providers };
381+
*providers = Providers { thir_abstract_const, ..*providers };
436382
}

‎tests/crashes/131052.rs‎

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/131052>
2+
3+
#![feature(adt_const_params)]
4+
5+
struct ConstBytes<const T: &'static [*mut u8; 3]>;
6+
//~^ ERROR `&'static [*mut u8; 3]` can't be used as a const parameter type
7+
8+
pub fn main() {
9+
let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">;
10+
//~^ ERROR mismatched types
11+
//~| ERROR mismatched types
12+
//~| ERROR mismatched types
13+
}

0 commit comments

Comments
 (0)