Skip to content

Commit 1c0235e

Browse files
committed
Auto merge of rust-lang#14802 - HKalbasi:layout, r=HKalbasi
Fix layout for `hir_ty::Ty` and friends
2 parents 0a806fe + 261047d commit 1c0235e

File tree

9 files changed

+89
-30
lines changed

9 files changed

+89
-30
lines changed

Diff for: crates/hir-ty/src/consteval/tests.rs

+30
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,36 @@ fn const_generic_subst_fn() {
19621962
);
19631963
}
19641964

1965+
#[test]
1966+
fn layout_of_type_with_associated_type_field_defined_inside_body() {
1967+
check_number(
1968+
r#"
1969+
trait Tr {
1970+
type Ty;
1971+
}
1972+
1973+
struct St<T: Tr>(T::Ty);
1974+
1975+
const GOAL: i64 = {
1976+
// if we move `St2` out of body, the test will fail, as we don't see the impl anymore. That
1977+
// case will probably be rejected by rustc in some later edition, but we should support this
1978+
// case.
1979+
struct St2;
1980+
1981+
impl Tr for St2 {
1982+
type Ty = i64;
1983+
}
1984+
1985+
struct Goal(St<St2>);
1986+
1987+
let x = Goal(St(5));
1988+
x.0.0
1989+
};
1990+
"#,
1991+
5,
1992+
);
1993+
}
1994+
19651995
#[test]
19661996
fn const_generic_subst_assoc_const_impl() {
19671997
check_number(

Diff for: crates/hir-ty/src/db.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
7474

7575
#[salsa::invoke(crate::layout::layout_of_adt_query)]
7676
#[salsa::cycle(crate::layout::layout_of_adt_recover)]
77-
fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result<Layout, LayoutError>;
77+
fn layout_of_adt(
78+
&self,
79+
def: AdtId,
80+
subst: Substitution,
81+
krate: CrateId,
82+
) -> Result<Layout, LayoutError>;
7883

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

Diff for: crates/hir-ty/src/display.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ fn render_const_scalar(
463463
memory_map: &MemoryMap,
464464
ty: &Ty,
465465
) -> Result<(), HirDisplayError> {
466+
// FIXME: We need to get krate from the final callers of the hir display
467+
// infrastructure and have it here as a field on `f`.
468+
let krate = *f.db.crate_graph().crates_in_topological_order().last().unwrap();
466469
match ty.kind(Interner) {
467470
chalk_ir::TyKind::Scalar(s) => match s {
468471
Scalar::Bool => write!(f, "{}", if b[0] == 0 { false } else { true }),
@@ -502,11 +505,6 @@ fn render_const_scalar(
502505
_ => f.write_str("<ref-not-supported>"),
503506
},
504507
chalk_ir::TyKind::Tuple(_, subst) => {
505-
// FIXME: Remove this line. If the target data layout is independent
506-
// of the krate, the `db.target_data_layout` and its callers like `layout_of_ty` don't need
507-
// to get krate. Otherwise, we need to get krate from the final callers of the hir display
508-
// infrastructure and have it here as a field on `f`.
509-
let krate = *f.db.crate_graph().crates_in_topological_order().last().unwrap();
510508
let Ok(layout) = layout_of_ty(f.db, ty, krate) else {
511509
return f.write_str("<layout-error>");
512510
};
@@ -532,7 +530,7 @@ fn render_const_scalar(
532530
chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
533531
hir_def::AdtId::StructId(s) => {
534532
let data = f.db.struct_data(s);
535-
let Ok(layout) = f.db.layout_of_adt(adt.0, subst.clone()) else {
533+
let Ok(layout) = f.db.layout_of_adt(adt.0, subst.clone(), krate) else {
536534
return f.write_str("<layout-error>");
537535
};
538536
match data.variant_data.as_ref() {

Diff for: crates/hir-ty/src/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
8484
let trait_env = Arc::new(TraitEnvironment::empty(krate));
8585
let ty = normalize(db, trait_env, ty.clone());
8686
Ok(match ty.kind(Interner) {
87-
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,
87+
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone(), krate)?,
8888
TyKind::Scalar(s) => match s {
8989
chalk_ir::Scalar::Bool => Layout::scalar(
9090
dl,

Diff for: crates/hir-ty/src/layout/adt.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
33
use std::{cmp, ops::Bound};
44

5+
use base_db::CrateId;
56
use hir_def::{
67
data::adt::VariantData,
78
layout::{Integer, LayoutCalculator, ReprOptions, TargetDataLayout},
8-
AdtId, EnumVariantId, HasModule, LocalEnumVariantId, VariantId,
9+
AdtId, EnumVariantId, LocalEnumVariantId, VariantId,
910
};
1011
use la_arena::RawIdx;
1112
use smallvec::SmallVec;
@@ -27,8 +28,8 @@ pub fn layout_of_adt_query(
2728
db: &dyn HirDatabase,
2829
def: AdtId,
2930
subst: Substitution,
31+
krate: CrateId,
3032
) -> Result<Layout, LayoutError> {
31-
let krate = def.module(db.upcast()).krate();
3233
let Some(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable) };
3334
let cx = LayoutCx { krate, target: &target };
3435
let dl = cx.current_data_layout();
@@ -127,6 +128,7 @@ pub fn layout_of_adt_recover(
127128
_: &[String],
128129
_: &AdtId,
129130
_: &Substitution,
131+
_: &CrateId,
130132
) -> Result<Layout, LayoutError> {
131133
user_error!("infinite sized recursive type");
132134
}

Diff for: crates/hir-ty/src/layout/tests.rs

+40-16
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,25 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
2525
"{minicore}//- /main.rs crate:test target_data_layout:{target_data_layout}\n{ra_fixture}",
2626
);
2727

28-
let (db, file_id) = TestDB::with_single_file(&ra_fixture);
29-
let module_id = db.module_for_file(file_id);
30-
let def_map = module_id.def_map(&db);
31-
let scope = &def_map[module_id.local_id].scope;
32-
let adt_id = scope
33-
.declarations()
34-
.find_map(|x| match x {
35-
hir_def::ModuleDefId::AdtId(x) => {
36-
let name = match x {
37-
hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(),
38-
hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(),
39-
hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(),
40-
};
41-
(name == "Goal").then_some(x)
42-
}
43-
_ => None,
28+
let (db, file_ids) = TestDB::with_many_files(&ra_fixture);
29+
let (adt_id, module_id) = file_ids
30+
.into_iter()
31+
.find_map(|file_id| {
32+
let module_id = db.module_for_file(file_id);
33+
let def_map = module_id.def_map(&db);
34+
let scope = &def_map[module_id.local_id].scope;
35+
let adt_id = scope.declarations().find_map(|x| match x {
36+
hir_def::ModuleDefId::AdtId(x) => {
37+
let name = match x {
38+
hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(),
39+
hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(),
40+
hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(),
41+
};
42+
(name == "Goal").then_some(x)
43+
}
44+
_ => None,
45+
})?;
46+
Some((adt_id, module_id))
4447
})
4548
.unwrap();
4649
let goal_ty = TyKind::Adt(AdtId(adt_id), Substitution::empty(Interner)).intern(Interner);
@@ -232,6 +235,27 @@ fn associated_types() {
232235
struct Foo<A: Tr>(<A as Tr>::Ty);
233236
struct Goal(Foo<i32>);
234237
}
238+
check_size_and_align(
239+
r#"
240+
//- /b/mod.rs crate:b
241+
pub trait Tr {
242+
type Ty;
243+
}
244+
pub struct Foo<A: Tr>(<A as Tr>::Ty);
245+
246+
//- /a/mod.rs crate:a deps:b
247+
use b::{Tr, Foo};
248+
249+
struct S;
250+
impl Tr for S {
251+
type Ty = i64;
252+
}
253+
struct Goal(Foo<S>);
254+
"#,
255+
"",
256+
8,
257+
8,
258+
);
235259
}
236260

237261
#[test]

Diff for: crates/hir-ty/src/mir/eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ impl Evaluator<'_> {
574574
}
575575

576576
fn layout_adt(&self, adt: AdtId, subst: Substitution) -> Result<Layout> {
577-
self.db.layout_of_adt(adt, subst.clone()).map_err(|e| {
577+
self.db.layout_of_adt(adt, subst.clone(), self.crate_id).map_err(|e| {
578578
MirEvalError::LayoutError(e, TyKind::Adt(chalk_ir::AdtId(adt), subst).intern(Interner))
579579
})
580580
}

Diff for: crates/hir/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ impl Adt {
12071207
if db.generic_params(self.into()).iter().count() != 0 {
12081208
return Err(LayoutError::HasPlaceholder);
12091209
}
1210-
db.layout_of_adt(self.into(), Substitution::empty(Interner))
1210+
db.layout_of_adt(self.into(), Substitution::empty(Interner), self.krate(db).id)
12111211
}
12121212

12131213
/// Turns this ADT into a type. Any type parameters of the ADT will be

Diff for: crates/rust-analyzer/src/cli/analysis_stats.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88

99
use hir::{
1010
db::{DefDatabase, ExpandDatabase, HirDatabase},
11-
AssocItem, Crate, Function, HasSource, HirDisplay, ModuleDef,
11+
AssocItem, Crate, Function, HasCrate, HasSource, HirDisplay, ModuleDef,
1212
};
1313
use hir_def::{
1414
body::{BodySourceMap, SyntheticSyntax},
@@ -210,7 +210,7 @@ impl flags::AnalysisStats {
210210
continue;
211211
}
212212
all += 1;
213-
let Err(e) = db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner)) else {
213+
let Err(e) = db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner), a.krate(db).into()) else {
214214
continue;
215215
};
216216
if verbosity.is_spammy() {

0 commit comments

Comments
 (0)