Skip to content

Commit 6b8eb75

Browse files
committed
Auto merge of #15316 - HKalbasi:mir, r=HKalbasi
Pass `TraitEnvironment` into `layout_ty` and `const_eval` We need to do either this or get rid of trait environment in `normalize_ty`. Let's go with this for now.
2 parents cecbd3f + eb14338 commit 6b8eb75

File tree

14 files changed

+149
-87
lines changed

14 files changed

+149
-87
lines changed

crates/hir-ty/src/consteval.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use triomphe::Arc;
1616
use crate::{
1717
db::HirDatabase, infer::InferenceContext, lower::ParamLoweringMode,
1818
mir::monomorphize_mir_body_bad, to_placeholder_idx, utils::Generics, Const, ConstData,
19-
ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, Ty, TyBuilder,
19+
ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty,
20+
TyBuilder,
2021
};
2122

2223
use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError};
@@ -135,7 +136,7 @@ pub fn intern_const_ref(
135136
ty: Ty,
136137
krate: CrateId,
137138
) -> Const {
138-
let layout = db.layout_of_ty(ty.clone(), krate);
139+
let layout = db.layout_of_ty(ty.clone(), Arc::new(TraitEnvironment::empty(krate)));
139140
let bytes = match value {
140141
LiteralConstRef::Int(i) => {
141142
// FIXME: We should handle failure of layout better.
@@ -173,7 +174,7 @@ pub fn try_const_usize(db: &dyn HirDatabase, c: &Const) -> Option<u128> {
173174
chalk_ir::ConstValue::Concrete(c) => match &c.interned {
174175
ConstScalar::Bytes(it, _) => Some(u128::from_le_bytes(pad16(&it, false))),
175176
ConstScalar::UnevaluatedConst(c, subst) => {
176-
let ec = db.const_eval(*c, subst.clone()).ok()?;
177+
let ec = db.const_eval(*c, subst.clone(), None).ok()?;
177178
try_const_usize(db, &ec)
178179
}
179180
_ => None,
@@ -186,6 +187,7 @@ pub(crate) fn const_eval_recover(
186187
_: &[String],
187188
_: &GeneralConstId,
188189
_: &Substitution,
190+
_: &Option<Arc<TraitEnvironment>>,
189191
) -> Result<Const, ConstEvalError> {
190192
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
191193
}
@@ -210,6 +212,7 @@ pub(crate) fn const_eval_query(
210212
db: &dyn HirDatabase,
211213
def: GeneralConstId,
212214
subst: Substitution,
215+
trait_env: Option<Arc<TraitEnvironment>>,
213216
) -> Result<Const, ConstEvalError> {
214217
let body = match def {
215218
GeneralConstId::ConstId(c) => {
@@ -228,7 +231,7 @@ pub(crate) fn const_eval_query(
228231
}
229232
GeneralConstId::InTypeConstId(c) => db.mir_body(c.into())?,
230233
};
231-
let c = interpret_mir(db, body, false).0?;
234+
let c = interpret_mir(db, body, false, trait_env).0?;
232235
Ok(c)
233236
}
234237

@@ -241,7 +244,7 @@ pub(crate) fn const_eval_static_query(
241244
Substitution::empty(Interner),
242245
db.trait_environment_for_body(def.into()),
243246
)?;
244-
let c = interpret_mir(db, body, false).0?;
247+
let c = interpret_mir(db, body, false, None).0?;
245248
Ok(c)
246249
}
247250

@@ -268,7 +271,7 @@ pub(crate) fn const_eval_discriminant_variant(
268271
Substitution::empty(Interner),
269272
db.trait_environment_for_body(def),
270273
)?;
271-
let c = interpret_mir(db, mir_body, false).0?;
274+
let c = interpret_mir(db, mir_body, false, None).0?;
272275
let c = try_const_usize(db, &c).unwrap() as i128;
273276
Ok(c)
274277
}
@@ -293,7 +296,7 @@ pub(crate) fn eval_to_const(
293296
}
294297
let infer = ctx.clone().resolve_all();
295298
if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) {
296-
if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true).0 {
299+
if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true, None).0 {
297300
return result;
298301
}
299302
}

crates/hir-ty/src/consteval/tests.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ fn eval_goal(db: &TestDB, file_id: FileId) -> Result<Const, ConstEvalError> {
114114
_ => None,
115115
})
116116
.expect("No const named GOAL found in the test");
117-
db.const_eval(const_id.into(), Substitution::empty(Interner))
117+
db.const_eval(const_id.into(), Substitution::empty(Interner), None)
118118
}
119119

120120
#[test]
@@ -2492,6 +2492,28 @@ fn const_trait_assoc() {
24922492
"#,
24932493
5,
24942494
);
2495+
check_number(
2496+
r#"
2497+
//- minicore: size_of
2498+
//- /a/lib.rs crate:a
2499+
use core::mem::size_of;
2500+
pub struct S<T>(T);
2501+
impl<T> S<T> {
2502+
pub const X: usize = core::mem::size_of::<T>();
2503+
}
2504+
//- /main.rs crate:main deps:a
2505+
use a::{S};
2506+
trait Tr {
2507+
type Ty;
2508+
}
2509+
impl Tr for i32 {
2510+
type Ty = u64;
2511+
}
2512+
struct K<T: Tr>(<T as Tr>::Ty);
2513+
const GOAL: usize = S::<K<i32>>::X;
2514+
"#,
2515+
8,
2516+
);
24952517
check_number(
24962518
r#"
24972519
struct S<T>(*mut T);

crates/hir-ty/src/db.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
7777

7878
#[salsa::invoke(crate::consteval::const_eval_query)]
7979
#[salsa::cycle(crate::consteval::const_eval_recover)]
80-
fn const_eval(&self, def: GeneralConstId, subst: Substitution)
81-
-> Result<Const, ConstEvalError>;
80+
fn const_eval(
81+
&self,
82+
def: GeneralConstId,
83+
subst: Substitution,
84+
trait_env: Option<Arc<crate::TraitEnvironment>>,
85+
) -> Result<Const, ConstEvalError>;
8286

8387
#[salsa::invoke(crate::consteval::const_eval_static_query)]
8488
#[salsa::cycle(crate::consteval::const_eval_static_recover)]
@@ -100,12 +104,16 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
100104
&self,
101105
def: AdtId,
102106
subst: Substitution,
103-
krate: CrateId,
107+
env: Arc<crate::TraitEnvironment>,
104108
) -> Result<Arc<Layout>, LayoutError>;
105109

106110
#[salsa::invoke(crate::layout::layout_of_ty_query)]
107111
#[salsa::cycle(crate::layout::layout_of_ty_recover)]
108-
fn layout_of_ty(&self, ty: Ty, krate: CrateId) -> Result<Arc<Layout>, LayoutError>;
112+
fn layout_of_ty(
113+
&self,
114+
ty: Ty,
115+
env: Arc<crate::TraitEnvironment>,
116+
) -> Result<Arc<Layout>, LayoutError>;
109117

110118
#[salsa::invoke(crate::layout::target_data_layout_query)]
111119
fn target_data_layout(&self, krate: CrateId) -> Option<Arc<TargetDataLayout>>;

crates/hir-ty/src/display.rs

+17-14
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use itertools::Itertools;
2929
use la_arena::ArenaMap;
3030
use smallvec::SmallVec;
3131
use stdx::never;
32+
use triomphe::Arc;
3233

3334
use crate::{
3435
consteval::try_const_usize,
@@ -43,7 +44,7 @@ use crate::{
4344
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstScalar, ConstValue,
4445
DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives,
4546
MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar,
46-
Substitution, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
47+
Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
4748
};
4849

4950
pub trait HirWrite: fmt::Write {
@@ -454,7 +455,9 @@ fn render_const_scalar(
454455
) -> Result<(), HirDisplayError> {
455456
// FIXME: We need to get krate from the final callers of the hir display
456457
// infrastructure and have it here as a field on `f`.
457-
let krate = *f.db.crate_graph().crates_in_topological_order().last().unwrap();
458+
let trait_env = Arc::new(TraitEnvironment::empty(
459+
*f.db.crate_graph().crates_in_topological_order().last().unwrap(),
460+
));
458461
match ty.kind(Interner) {
459462
TyKind::Scalar(s) => match s {
460463
Scalar::Bool => write!(f, "{}", if b[0] == 0 { false } else { true }),
@@ -497,7 +500,7 @@ fn render_const_scalar(
497500
TyKind::Slice(ty) => {
498501
let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
499502
let count = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
500-
let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
503+
let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env) else {
501504
return f.write_str("<layout-error>");
502505
};
503506
let size_one = layout.size.bytes_usize();
@@ -523,7 +526,7 @@ fn render_const_scalar(
523526
let Ok(t) = memory_map.vtable.ty(ty_id) else {
524527
return f.write_str("<ty-missing-in-vtable-map>");
525528
};
526-
let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
529+
let Ok(layout) = f.db.layout_of_ty(t.clone(), trait_env) else {
527530
return f.write_str("<layout-error>");
528531
};
529532
let size = layout.size.bytes_usize();
@@ -555,7 +558,7 @@ fn render_const_scalar(
555558
return f.write_str("<layout-error>");
556559
}
557560
});
558-
let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
561+
let Ok(layout) = f.db.layout_of_ty(t.clone(), trait_env) else {
559562
return f.write_str("<layout-error>");
560563
};
561564
let size = layout.size.bytes_usize();
@@ -567,7 +570,7 @@ fn render_const_scalar(
567570
}
568571
},
569572
TyKind::Tuple(_, subst) => {
570-
let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
573+
let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env.clone()) else {
571574
return f.write_str("<layout-error>");
572575
};
573576
f.write_str("(")?;
@@ -580,7 +583,7 @@ fn render_const_scalar(
580583
}
581584
let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
582585
let offset = layout.fields.offset(id).bytes_usize();
583-
let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
586+
let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env.clone()) else {
584587
f.write_str("<layout-error>")?;
585588
continue;
586589
};
@@ -590,7 +593,7 @@ fn render_const_scalar(
590593
f.write_str(")")
591594
}
592595
TyKind::Adt(adt, subst) => {
593-
let Ok(layout) = f.db.layout_of_adt(adt.0, subst.clone(), krate) else {
596+
let Ok(layout) = f.db.layout_of_adt(adt.0, subst.clone(), trait_env.clone()) else {
594597
return f.write_str("<layout-error>");
595598
};
596599
match adt.0 {
@@ -602,7 +605,7 @@ fn render_const_scalar(
602605
&data.variant_data,
603606
f,
604607
&field_types,
605-
adt.0.module(f.db.upcast()).krate(),
608+
f.db.trait_environment(adt.0.into()),
606609
&layout,
607610
subst,
608611
b,
@@ -614,7 +617,7 @@ fn render_const_scalar(
614617
}
615618
hir_def::AdtId::EnumId(e) => {
616619
let Some((var_id, var_layout)) =
617-
detect_variant_from_bytes(&layout, f.db, krate, b, e)
620+
detect_variant_from_bytes(&layout, f.db, trait_env.clone(), b, e)
618621
else {
619622
return f.write_str("<failed-to-detect-variant>");
620623
};
@@ -626,7 +629,7 @@ fn render_const_scalar(
626629
&data.variant_data,
627630
f,
628631
&field_types,
629-
adt.0.module(f.db.upcast()).krate(),
632+
f.db.trait_environment(adt.0.into()),
630633
&var_layout,
631634
subst,
632635
b,
@@ -645,7 +648,7 @@ fn render_const_scalar(
645648
let Some(len) = try_const_usize(f.db, len) else {
646649
return f.write_str("<unknown-array-len>");
647650
};
648-
let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
651+
let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env) else {
649652
return f.write_str("<layout-error>");
650653
};
651654
let size_one = layout.size.bytes_usize();
@@ -684,7 +687,7 @@ fn render_variant_after_name(
684687
data: &VariantData,
685688
f: &mut HirFormatter<'_>,
686689
field_types: &ArenaMap<LocalFieldId, Binders<Ty>>,
687-
krate: CrateId,
690+
trait_env: Arc<TraitEnvironment>,
688691
layout: &Layout,
689692
subst: &Substitution,
690693
b: &[u8],
@@ -695,7 +698,7 @@ fn render_variant_after_name(
695698
let render_field = |f: &mut HirFormatter<'_>, id: LocalFieldId| {
696699
let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize();
697700
let ty = field_types[id].clone().substitute(Interner, subst);
698-
let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
701+
let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env.clone()) else {
699702
return f.write_str("<layout-error>");
700703
};
701704
let size = layout.size.bytes_usize();

crates/hir-ty/src/infer/unify.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ impl<'a> InferenceTable<'a> {
252252
// and registering an obligation. But it needs chalk support, so we handle the most basic
253253
// case (a non associated const without generic parameters) manually.
254254
if subst.len(Interner) == 0 {
255-
if let Ok(eval) = self.db.const_eval((*c_id).into(), subst.clone())
255+
if let Ok(eval) =
256+
self.db.const_eval((*c_id).into(), subst.clone(), None)
256257
{
257258
eval
258259
} else {
@@ -785,7 +786,7 @@ impl<'a> InferenceTable<'a> {
785786
crate::ConstScalar::Unknown => self.new_const_var(data.ty.clone()),
786787
// try to evaluate unevaluated const. Replace with new var if const eval failed.
787788
crate::ConstScalar::UnevaluatedConst(id, subst) => {
788-
if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
789+
if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
789790
eval
790791
} else {
791792
self.new_const_var(data.ty.clone())

0 commit comments

Comments
 (0)