1use rustc_abi::{BackendRepr, FieldIdx, VariantIdx};
2use rustc_data_structures::fx::{FxHashMap, FxHashSet};
3use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError};
4use rustc_middle::traits::ObligationCause;
5use rustc_middle::ty::layout::{LayoutCx, TyAndLayout};
6use rustc_middle::ty::{self, Ty, TyCtxt};
7use rustc_middle::{bug, mir};
8use rustc_span::DUMMY_SP;
9use tracing::{debug, instrument, trace};
10
11use super::VALTREE_MAX_NODES;
12use super::eval_queries::{mk_eval_cx_to_read_const_val, op_to_const};
13use super::machine::CompileTimeInterpCx;
14use crate::const_eval::CanAccessMutGlobal;
15use crate::interpret::{
16 ImmTy, Immediate, InternKind, MPlaceTy, MemPlaceMeta, MemoryKind, PlaceTy, Projectable, Scalar,
17 intern_const_alloc_recursive,
18};
19
20#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("branches",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(20u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place")
}> =
::tracing::__macro_support::FieldName::new("place");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("field_count")
}> =
::tracing::__macro_support::FieldName::new("field_count");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("variant")
}> =
::tracing::__macro_support::FieldName::new("variant");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("num_nodes")
}> =
::tracing::__macro_support::FieldName::new("num_nodes");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&field_count as
&dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&variant)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&num_nodes as
&dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: EvalToValTreeResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
let place =
match variant {
Some(variant) =>
ecx.project_downcast(place, variant).unwrap(),
None => place.clone(),
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:34",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(34u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place")
}> =
::tracing::__macro_support::FieldName::new("place");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let mut branches =
Vec::with_capacity(field_count + variant.is_some() as usize);
if let Some(variant) = variant {
branches.push(ty::Const::new_value(*ecx.tcx,
ty::ValTree::from_scalar_int(*ecx.tcx,
variant.as_u32().into()), ecx.tcx.types.u32));
}
for i in 0..field_count {
let field =
ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();
let valtree =
const_to_valtree_inner(ecx, &field, num_nodes, visited,
settled)?;
branches.push(ty::Const::new_value(*ecx.tcx, valtree,
field.layout.ty));
}
if branches.len() == 0 { *num_nodes += 1; }
Ok(ty::ValTree::from_branches(*ecx.tcx, branches))
}
}
}#[instrument(skip(ecx, visited, settled), level = "debug")]
21fn branches<'tcx>(
22 ecx: &CompileTimeInterpCx<'tcx>,
23 place: &MPlaceTy<'tcx>,
24 field_count: usize,
25 variant: Option<VariantIdx>,
26 num_nodes: &mut usize,
27 visited: &mut FxHashSet<MPlaceTy<'tcx>>,
28 settled: &mut FxHashMap<MPlaceTy<'tcx>, EvalToValTreeResult<'tcx>>,
29) -> EvalToValTreeResult<'tcx> {
30 let place = match variant {
31 Some(variant) => ecx.project_downcast(place, variant).unwrap(),
32 None => place.clone(),
33 };
34 debug!(?place);
35
36 let mut branches = Vec::with_capacity(field_count + variant.is_some() as usize);
37
38 if let Some(variant) = variant {
41 branches.push(ty::Const::new_value(
42 *ecx.tcx,
43 ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into()),
44 ecx.tcx.types.u32,
45 ));
46 }
47
48 for i in 0..field_count {
49 let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();
50 let valtree = const_to_valtree_inner(ecx, &field, num_nodes, visited, settled)?;
51 branches.push(ty::Const::new_value(*ecx.tcx, valtree, field.layout.ty));
52 }
53
54 if branches.len() == 0 {
56 *num_nodes += 1;
57 }
58
59 Ok(ty::ValTree::from_branches(*ecx.tcx, branches))
60}
61
62#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("slice_branches",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(62u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place")
}> =
::tracing::__macro_support::FieldName::new("place");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("num_nodes")
}> =
::tracing::__macro_support::FieldName::new("num_nodes");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&num_nodes as
&dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: EvalToValTreeResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
let n =
place.len(ecx).unwrap_or_else(|_|
{
::core::panicking::panic_fmt(format_args!("expected to use len of place {0:?}",
place));
});
let mut elems = Vec::with_capacity(n as usize);
for i in 0..n {
let place_elem = ecx.project_index(place, i).unwrap();
let valtree =
const_to_valtree_inner(ecx, &place_elem, num_nodes, visited,
settled)?;
elems.push(ty::Const::new_value(*ecx.tcx, valtree,
place_elem.layout.ty));
}
Ok(ty::ValTree::from_branches(*ecx.tcx, elems))
}
}
}#[instrument(skip(ecx, visited, settled), level = "debug")]
63fn slice_branches<'tcx>(
64 ecx: &CompileTimeInterpCx<'tcx>,
65 place: &MPlaceTy<'tcx>,
66 num_nodes: &mut usize,
67 visited: &mut FxHashSet<MPlaceTy<'tcx>>,
68 settled: &mut FxHashMap<MPlaceTy<'tcx>, EvalToValTreeResult<'tcx>>,
69) -> EvalToValTreeResult<'tcx> {
70 let n = place.len(ecx).unwrap_or_else(|_| panic!("expected to use len of place {place:?}"));
71
72 let mut elems = Vec::with_capacity(n as usize);
73 for i in 0..n {
74 let place_elem = ecx.project_index(place, i).unwrap();
75 let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes, visited, settled)?;
76 elems.push(ty::Const::new_value(*ecx.tcx, valtree, place_elem.layout.ty));
77 }
78
79 Ok(ty::ValTree::from_branches(*ecx.tcx, elems))
80}
81
82#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("const_to_valtree_inner",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(82u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place")
}> =
::tracing::__macro_support::FieldName::new("place");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("num_nodes")
}> =
::tracing::__macro_support::FieldName::new("num_nodes");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&num_nodes as
&dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: EvalToValTreeResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
let tcx = *ecx.tcx;
let ty = place.layout.ty;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:92",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(92u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("ty kind: {0:?}",
ty.kind()) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
if let Some(&result) = settled.get(place) { return result; }
if visited.contains(place) {
return Err(ValTreeCreationError::CyclicConst);
}
if *num_nodes >= VALTREE_MAX_NODES {
return Err(ValTreeCreationError::NodesOverflow);
}
visited.insert(place.clone());
let result =
match ty.kind() {
ty::FnDef(..) => {
*num_nodes += 1;
Ok(ty::ValTree::zst(tcx))
}
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) |
ty::Char => {
let val = ecx.read_immediate(place).report_err()?;
let val = val.to_scalar_int().unwrap();
*num_nodes += 1;
Ok(ty::ValTree::from_scalar_int(tcx, val))
}
ty::Pat(base, ..) => {
let mut place = place.clone();
place.layout = ecx.layout_of(*base).unwrap();
const_to_valtree_inner(ecx, &place, num_nodes, visited,
settled)
}
ty::RawPtr(_, _) => {
let val = ecx.read_immediate(place).report_err()?;
if #[allow(non_exhaustive_omitted_patterns)] match val.layout.backend_repr
{
BackendRepr::ScalarPair { .. } => true,
_ => false,
} {
Err(ValTreeCreationError::NonSupportedType(ty))
} else {
let val = val.to_scalar();
match val.try_to_scalar_int() {
Ok(val) => Ok(ty::ValTree::from_scalar_int(tcx, val)),
Err(_) => Err(ValTreeCreationError::NonSupportedType(ty)),
}
}
}
ty::FnPtr(..) =>
Err(ValTreeCreationError::NonSupportedType(ty)),
ty::Ref(_, _, _) => {
let derefd_place = ecx.deref_pointer(place).report_err()?;
const_to_valtree_inner(ecx, &derefd_place, num_nodes,
visited, settled)
}
ty::Str | ty::Slice(_) | ty::Array(_, _) => {
slice_branches(ecx, place, num_nodes, visited, settled)
}
ty::Dynamic(..) =>
Err(ValTreeCreationError::NonSupportedType(ty)),
ty::Tuple(elem_tys) => {
branches(ecx, place, elem_tys.len(), None, num_nodes,
visited, settled)
}
ty::Adt(def, _) => {
if def.is_union() {
Err(ValTreeCreationError::NonSupportedType(ty))
} else if def.variants().is_empty() {
::rustc_middle::util::bug::bug_fmt(format_args!("uninhabited types should have errored and never gotten converted to valtree"))
} else {
let variant = ecx.read_discriminant(place).report_err()?;
branches(ecx, place, def.variant(variant).fields.len(),
def.is_enum().then_some(variant), num_nodes, visited,
settled)
}
}
ty::Alias(..) =>
Err(ValTreeCreationError::NonSupportedType(ty)),
ty::Closure(..) =>
Err(ValTreeCreationError::NonSupportedType(ty)),
ty::Never | ty::Error(_) | ty::Foreign(..) |
ty::Infer(ty::FreshIntTy(_)) |
ty::Infer(ty::FreshFloatTy(_)) | ty::Param(_) |
ty::Bound(..) | ty::Placeholder(..) | ty::Infer(_) |
ty::CoroutineClosure(..) | ty::Coroutine(..) |
ty::CoroutineWitness(..) | ty::UnsafeBinder(_) =>
Err(ValTreeCreationError::NonSupportedType(ty)),
};
visited.remove(place);
settled.insert(place.clone(), result);
result
}
}
}#[instrument(skip(ecx, visited, settled), level = "debug")]
83fn const_to_valtree_inner<'tcx>(
84 ecx: &CompileTimeInterpCx<'tcx>,
85 place: &MPlaceTy<'tcx>,
86 num_nodes: &mut usize,
87 visited: &mut FxHashSet<MPlaceTy<'tcx>>,
88 settled: &mut FxHashMap<MPlaceTy<'tcx>, EvalToValTreeResult<'tcx>>,
89) -> EvalToValTreeResult<'tcx> {
90 let tcx = *ecx.tcx;
91 let ty = place.layout.ty;
92 debug!("ty kind: {:?}", ty.kind());
93
94 if let Some(&result) = settled.get(place) {
95 return result;
96 }
97
98 if visited.contains(place) {
99 return Err(ValTreeCreationError::CyclicConst);
100 }
101
102 if *num_nodes >= VALTREE_MAX_NODES {
103 return Err(ValTreeCreationError::NodesOverflow);
104 }
105
106 visited.insert(place.clone());
107
108 let result = match ty.kind() {
109 ty::FnDef(..) => {
110 *num_nodes += 1;
111 Ok(ty::ValTree::zst(tcx))
112 }
113 ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
114 let val = ecx.read_immediate(place).report_err()?;
115 let val = val.to_scalar_int().unwrap();
116 *num_nodes += 1;
117
118 Ok(ty::ValTree::from_scalar_int(tcx, val))
119 }
120
121 ty::Pat(base, ..) => {
122 let mut place = place.clone();
123 place.layout = ecx.layout_of(*base).unwrap();
127 const_to_valtree_inner(ecx, &place, num_nodes, visited, settled)
128 }
129
130 ty::RawPtr(_, _) => {
131 let val = ecx.read_immediate(place).report_err()?;
136 if matches!(val.layout.backend_repr, BackendRepr::ScalarPair { .. }) {
139 Err(ValTreeCreationError::NonSupportedType(ty))
140 } else {
141 let val = val.to_scalar();
142 match val.try_to_scalar_int() {
145 Ok(val) => Ok(ty::ValTree::from_scalar_int(tcx, val)),
146 Err(_) => Err(ValTreeCreationError::NonSupportedType(ty)),
147 }
148 }
149 }
150
151 ty::FnPtr(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
154
155 ty::Ref(_, _, _) => {
156 let derefd_place = ecx.deref_pointer(place).report_err()?;
157 const_to_valtree_inner(ecx, &derefd_place, num_nodes, visited, settled)
158 }
159
160 ty::Str | ty::Slice(_) | ty::Array(_, _) => {
161 slice_branches(ecx, place, num_nodes, visited, settled)
162 }
163 ty::Dynamic(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
168
169 ty::Tuple(elem_tys) => {
170 branches(ecx, place, elem_tys.len(), None, num_nodes, visited, settled)
171 }
172
173 ty::Adt(def, _) => {
174 if def.is_union() {
175 Err(ValTreeCreationError::NonSupportedType(ty))
176 } else if def.variants().is_empty() {
177 bug!("uninhabited types should have errored and never gotten converted to valtree")
178 } else {
179 let variant = ecx.read_discriminant(place).report_err()?;
180 branches(
181 ecx,
182 place,
183 def.variant(variant).fields.len(),
184 def.is_enum().then_some(variant),
185 num_nodes,
186 visited,
187 settled,
188 )
189 }
190 }
191
192 ty::Alias(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
194
195 ty::Closure(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
197
198 ty::Never
199 | ty::Error(_)
200 | ty::Foreign(..)
201 | ty::Infer(ty::FreshIntTy(_))
202 | ty::Infer(ty::FreshFloatTy(_))
203 | ty::Param(_)
204 | ty::Bound(..)
205 | ty::Placeholder(..)
206 | ty::Infer(_)
207 | ty::CoroutineClosure(..)
208 | ty::Coroutine(..)
209 | ty::CoroutineWitness(..)
210 | ty::UnsafeBinder(_) => Err(ValTreeCreationError::NonSupportedType(ty)),
211 };
212
213 visited.remove(place);
214 settled.insert(place.clone(), result);
215 result
216}
217
218fn reconstruct_place_meta<'tcx>(
221 layout: TyAndLayout<'tcx>,
222 valtree: ty::ValTree<'tcx>,
223 tcx: TyCtxt<'tcx>,
224) -> MemPlaceMeta {
225 if layout.is_sized() {
226 return MemPlaceMeta::None;
227 }
228
229 let mut last_valtree = valtree;
230 let tail = tcx.struct_tail_raw(
234 layout.ty,
235 &ObligationCause::dummy(),
236 |ty| ty.skip_norm_wip(),
237 || {
238 let branches = last_valtree.to_branch();
239 last_valtree = branches.last().unwrap().to_value().valtree;
240 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:240",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(240u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("branches")
}> =
::tracing::__macro_support::FieldName::new("branches");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("last_valtree")
}> =
::tracing::__macro_support::FieldName::new("last_valtree");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&branches)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&last_valtree)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?branches, ?last_valtree);
241 },
242 );
243 match tail.kind() {
245 ty::Slice(..) | ty::Str => {}
246 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unsized tail of a valtree must be Slice or Str"))bug!("unsized tail of a valtree must be Slice or Str"),
247 };
248
249 let num_elems = last_valtree.to_branch().len();
251 MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx))
252}
253
254x;#[instrument(skip(ecx), level = "debug", ret)]
255fn create_valtree_place<'tcx>(
256 ecx: &mut CompileTimeInterpCx<'tcx>,
257 layout: TyAndLayout<'tcx>,
258 valtree: ty::ValTree<'tcx>,
259) -> MPlaceTy<'tcx> {
260 let meta = reconstruct_place_meta(layout, valtree, ecx.tcx.tcx);
261 ecx.allocate_dyn(layout, MemoryKind::Stack, meta).unwrap()
262}
263
264pub(crate) fn eval_to_valtree<'tcx>(
266 tcx: TyCtxt<'tcx>,
267 typing_env: ty::TypingEnv<'tcx>,
268 cid: GlobalId<'tcx>,
269) -> EvalToValTreeResult<'tcx> {
270 crate::assert_typing_mode(typing_env.typing_mode());
271 let const_alloc = tcx.eval_to_allocation_raw(typing_env.as_query_input(cid))?;
272
273 let ecx = mk_eval_cx_to_read_const_val(
275 tcx,
276 DUMMY_SP,
277 typing_env,
278 CanAccessMutGlobal::No,
281 );
282 let place = ecx.raw_const_to_mplace(const_alloc).unwrap();
283 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:283",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(283u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place")
}> =
::tracing::__macro_support::FieldName::new("place");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?place);
284
285 let mut num_nodes = 0;
286 let mut visited = FxHashSet::default();
287 let mut settled = FxHashMap::default();
288 const_to_valtree_inner(&ecx, &place, &mut num_nodes, &mut visited, &mut settled)
289}
290
291x;#[instrument(skip(tcx), level = "debug", ret)]
295pub fn valtree_to_const_value<'tcx>(
296 tcx: TyCtxt<'tcx>,
297 typing_env: ty::TypingEnv<'tcx>,
298 cv: ty::Value<'tcx>,
299) -> mir::ConstValue {
300 match *cv.ty.kind() {
307 ty::FnDef(..) => {
308 assert!(cv.valtree.is_zst());
309 mir::ConstValue::ZeroSized
310 }
311 ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_, _) => {
312 mir::ConstValue::Scalar(Scalar::Int(cv.to_leaf()))
313 }
314 ty::Pat(ty, _) => {
315 let cv = ty::Value { valtree: cv.valtree, ty };
316 valtree_to_const_value(tcx, typing_env, cv)
317 }
318 ty::Ref(_, inner_ty, _) => {
319 let mut ecx =
320 mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
321 let imm = valtree_to_ref(&mut ecx, cv.valtree, inner_ty);
322 let imm = ImmTy::from_immediate(
323 imm,
324 tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap(),
325 );
326 op_to_const(&ecx, &imm.into(), false)
327 }
328 ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
329 let layout = tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap();
330 if layout.is_zst() {
331 return mir::ConstValue::ZeroSized;
333 }
334 if layout.backend_repr.is_scalar()
335 && (matches!(cv.ty.kind(), ty::Tuple(_))
336 || matches!(cv.ty.kind(), ty::Adt(def, _) if def.is_struct()))
337 {
338 let branches = cv.to_branch();
340 for (i, &inner_valtree) in branches.iter().enumerate() {
342 let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
343 if !field.is_zst() {
344 let cv =
345 ty::Value { valtree: inner_valtree.to_value().valtree, ty: field.ty };
346 return valtree_to_const_value(tcx, typing_env, cv);
347 }
348 }
349 bug!("could not find non-ZST field during in {layout:#?}");
350 }
351
352 let mut ecx =
353 mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
354
355 let place = create_valtree_place(&mut ecx, layout, cv.valtree);
357
358 valtree_into_mplace(&mut ecx, &place, cv.valtree);
359 dump_place(&ecx, &place);
360 intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
361
362 op_to_const(&ecx, &place.into(), false)
363 }
364 ty::Never
365 | ty::Error(_)
366 | ty::Foreign(..)
367 | ty::Infer(ty::FreshIntTy(_))
368 | ty::Infer(ty::FreshFloatTy(_))
369 | ty::Alias(..)
370 | ty::Param(_)
371 | ty::Bound(..)
372 | ty::Placeholder(..)
373 | ty::Infer(_)
374 | ty::Closure(..)
375 | ty::CoroutineClosure(..)
376 | ty::Coroutine(..)
377 | ty::CoroutineWitness(..)
378 | ty::FnPtr(..)
379 | ty::Str
380 | ty::Slice(_)
381 | ty::Dynamic(..)
382 | ty::UnsafeBinder(_) => {
383 bug!("no ValTree should have been created for type {:?}", cv.ty.kind())
384 }
385 }
386}
387
388fn valtree_to_ref<'tcx>(
390 ecx: &mut CompileTimeInterpCx<'tcx>,
391 valtree: ty::ValTree<'tcx>,
392 pointee_ty: Ty<'tcx>,
393) -> Immediate {
394 let pointee_place = create_valtree_place(ecx, ecx.layout_of(pointee_ty).unwrap(), valtree);
395 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:395",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(395u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("pointee_place")
}> =
::tracing::__macro_support::FieldName::new("pointee_place");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&pointee_place)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?pointee_place);
396
397 valtree_into_mplace(ecx, &pointee_place, valtree);
398 dump_place(ecx, &pointee_place);
399 intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap();
400
401 pointee_place.to_ref(&ecx.tcx)
402}
403
404#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("valtree_into_mplace",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(404u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place")
}> =
::tracing::__macro_support::FieldName::new("place");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("valtree")
}> =
::tracing::__macro_support::FieldName::new("valtree");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&valtree)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: () = loop {};
return __tracing_attr_fake_return;
}
{
let ty = place.layout.ty;
match ty.kind() {
ty::FnDef(_, _) => {}
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char
| ty::RawPtr(..) => {
let scalar_int = valtree.to_leaf();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:421",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(421u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("writing trivial valtree {0:?} to place {1:?}",
scalar_int, place) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
ecx.write_immediate(Immediate::Scalar(scalar_int.into()),
place).unwrap();
}
ty::Ref(_, inner_ty, _) => {
let imm = valtree_to_ref(ecx, valtree, *inner_ty);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:426",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(426u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("imm")
}> =
::tracing::__macro_support::FieldName::new("imm");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&imm)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
ecx.write_immediate(imm, place).unwrap();
}
ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str |
ty::Slice(_) => {
let branches = valtree.to_branch();
let (place_adjusted, branches, variant_idx) =
match ty.kind() {
ty::Adt(def, _) if def.is_enum() => {
let scalar_int = branches[0].to_leaf();
let variant_idx = VariantIdx::from_u32(scalar_int.to_u32());
let variant = def.variant(variant_idx);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:439",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(439u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("variant")
}> =
::tracing::__macro_support::FieldName::new("variant");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&variant)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
(ecx.project_downcast(place, variant_idx).unwrap(),
&branches[1..], Some(variant_idx))
}
_ => (place.clone(), branches.as_slice(), None),
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:449",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(449u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place_adjusted")
}> =
::tracing::__macro_support::FieldName::new("place_adjusted");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("branches")
}> =
::tracing::__macro_support::FieldName::new("branches");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place_adjusted)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&branches)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
for (i, inner_valtree) in branches.iter().enumerate() {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:454",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(454u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("i")
}> =
::tracing::__macro_support::FieldName::new("i");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("inner_valtree")
}> =
::tracing::__macro_support::FieldName::new("inner_valtree");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&i)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&inner_valtree)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let place_inner =
match ty.kind() {
ty::Str | ty::Slice(_) | ty::Array(..) => {
ecx.project_index(place, i as u64).unwrap()
}
_ =>
ecx.project_field(&place_adjusted,
FieldIdx::from_usize(i)).unwrap(),
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:463",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(463u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("place_inner")
}> =
::tracing::__macro_support::FieldName::new("place_inner");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place_inner)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
valtree_into_mplace(ecx, &place_inner,
inner_valtree.to_value().valtree);
dump_place(ecx, &place_inner);
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:468",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(468u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("dump of place_adjusted:")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
dump_place(ecx, &place_adjusted);
if let Some(variant_idx) = variant_idx {
ecx.write_discriminant(variant_idx, place).unwrap();
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:476",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(476u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("dump of place after writing discriminant:")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
dump_place(ecx, place);
}
_ =>
::rustc_middle::util::bug::bug_fmt(format_args!("shouldn\'t have created a ValTree for {0:?}",
ty)),
}
}
}
}#[instrument(skip(ecx), level = "debug")]
405fn valtree_into_mplace<'tcx>(
406 ecx: &mut CompileTimeInterpCx<'tcx>,
407 place: &MPlaceTy<'tcx>,
408 valtree: ty::ValTree<'tcx>,
409) {
410 let ty = place.layout.ty;
414
415 match ty.kind() {
416 ty::FnDef(_, _) => {
417 }
419 ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(..) => {
420 let scalar_int = valtree.to_leaf();
421 debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place);
422 ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap();
423 }
424 ty::Ref(_, inner_ty, _) => {
425 let imm = valtree_to_ref(ecx, valtree, *inner_ty);
426 debug!(?imm);
427 ecx.write_immediate(imm, place).unwrap();
428 }
429 ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => {
430 let branches = valtree.to_branch();
431
432 let (place_adjusted, branches, variant_idx) = match ty.kind() {
434 ty::Adt(def, _) if def.is_enum() => {
435 let scalar_int = branches[0].to_leaf();
437 let variant_idx = VariantIdx::from_u32(scalar_int.to_u32());
438 let variant = def.variant(variant_idx);
439 debug!(?variant);
440
441 (
442 ecx.project_downcast(place, variant_idx).unwrap(),
443 &branches[1..],
444 Some(variant_idx),
445 )
446 }
447 _ => (place.clone(), branches.as_slice(), None),
448 };
449 debug!(?place_adjusted, ?branches);
450
451 for (i, inner_valtree) in branches.iter().enumerate() {
454 debug!(?i, ?inner_valtree);
455
456 let place_inner = match ty.kind() {
457 ty::Str | ty::Slice(_) | ty::Array(..) => {
458 ecx.project_index(place, i as u64).unwrap()
459 }
460 _ => ecx.project_field(&place_adjusted, FieldIdx::from_usize(i)).unwrap(),
461 };
462
463 debug!(?place_inner);
464 valtree_into_mplace(ecx, &place_inner, inner_valtree.to_value().valtree);
465 dump_place(ecx, &place_inner);
466 }
467
468 debug!("dump of place_adjusted:");
469 dump_place(ecx, &place_adjusted);
470
471 if let Some(variant_idx) = variant_idx {
472 ecx.write_discriminant(variant_idx, place).unwrap();
474 }
475
476 debug!("dump of place after writing discriminant:");
477 dump_place(ecx, place);
478 }
479 _ => bug!("shouldn't have created a ValTree for {:?}", ty),
480 }
481}
482
483fn dump_place<'tcx>(ecx: &CompileTimeInterpCx<'tcx>, place: &MPlaceTy<'tcx>) {
484 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/valtrees.rs:484",
"rustc_const_eval::const_eval::valtrees",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/valtrees.rs"),
::tracing_core::__macro_support::Option::Some(484u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::valtrees"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("{0:?}",
ecx.dump_place(&PlaceTy::from(place.clone()))) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};trace!("{:?}", ecx.dump_place(&PlaceTy::from(place.clone())));
485}