Skip to content

Commit 051dae2

Browse files
committed
Support record pattern MIR lowering
1 parent 513e340 commit 051dae2

File tree

5 files changed

+200
-62
lines changed

5 files changed

+200
-62
lines changed

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

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,38 @@ fn structs() {
555555
"#,
556556
17,
557557
);
558+
check_number(
559+
r#"
560+
struct Point {
561+
x: i32,
562+
y: i32,
563+
}
564+
565+
const GOAL: i32 = {
566+
let p = Point { x: 5, y: 2 };
567+
let p2 = Point { x: 3, ..p };
568+
p.x * 1000 + p.y * 100 + p2.x * 10 + p2.y
569+
};
570+
"#,
571+
5232,
572+
);
573+
check_number(
574+
r#"
575+
struct Point {
576+
x: i32,
577+
y: i32,
578+
}
579+
580+
const GOAL: i32 = {
581+
let p = Point { x: 5, y: 2 };
582+
let Point { x, y } = p;
583+
let Point { x: x2, .. } = p;
584+
let Point { y: y2, .. } = p;
585+
x * 1000 + y * 100 + x2 * 10 + y2
586+
};
587+
"#,
588+
5252,
589+
);
558590
}
559591

560592
#[test]
@@ -599,13 +631,14 @@ fn tuples() {
599631
);
600632
check_number(
601633
r#"
602-
struct TupleLike(i32, u8, i64, u16);
603-
const GOAL: u8 = {
634+
struct TupleLike(i32, i64, u8, u16);
635+
const GOAL: i64 = {
604636
let a = TupleLike(10, 20, 3, 15);
605-
a.1
637+
let TupleLike(b, .., c) = a;
638+
a.1 * 100 + b as i64 + c as i64
606639
};
607640
"#,
608-
20,
641+
2025,
609642
);
610643
check_number(
611644
r#"

crates/hir-ty/src/method_resolution.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -711,12 +711,13 @@ pub fn is_dyn_method(
711711
};
712712
let self_ty = trait_ref.self_type_parameter(Interner);
713713
if let TyKind::Dyn(d) = self_ty.kind(Interner) {
714-
let is_my_trait_in_bounds = d.bounds.skip_binders().as_slice(Interner).iter().any(|x| match x.skip_binders() {
715-
// rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
716-
// what the generics are, we are sure that the method is come from the vtable.
717-
WhereClause::Implemented(tr) => tr.trait_id == trait_ref.trait_id,
718-
_ => false,
719-
});
714+
let is_my_trait_in_bounds =
715+
d.bounds.skip_binders().as_slice(Interner).iter().any(|x| match x.skip_binders() {
716+
// rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
717+
// what the generics are, we are sure that the method is come from the vtable.
718+
WhereClause::Implemented(tr) => tr.trait_id == trait_ref.trait_id,
719+
_ => false,
720+
});
720721
if is_my_trait_in_bounds {
721722
return Some(fn_params);
722723
}

crates/hir-ty/src/mir/eval.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use crate::{
2525
mapping::from_chalk,
2626
method_resolution::{is_dyn_method, lookup_impl_method},
2727
traits::FnTrait,
28-
CallableDefId, Const, ConstScalar, FnDefId, Interner, MemoryMap, Substitution,
29-
TraitEnvironment, Ty, TyBuilder, TyExt, GenericArgData,
28+
CallableDefId, Const, ConstScalar, FnDefId, GenericArgData, Interner, MemoryMap, Substitution,
29+
TraitEnvironment, Ty, TyBuilder, TyExt,
3030
};
3131

3232
use super::{
@@ -1315,10 +1315,13 @@ impl Evaluator<'_> {
13151315
args_for_target[0] = args_for_target[0][0..self.ptr_size()].to_vec();
13161316
let generics_for_target = Substitution::from_iter(
13171317
Interner,
1318-
generic_args
1319-
.iter(Interner)
1320-
.enumerate()
1321-
.map(|(i, x)| if i == self_ty_idx { &ty } else { x })
1318+
generic_args.iter(Interner).enumerate().map(|(i, x)| {
1319+
if i == self_ty_idx {
1320+
&ty
1321+
} else {
1322+
x
1323+
}
1324+
}),
13221325
);
13231326
return self.exec_fn_with_args(
13241327
def,

0 commit comments

Comments
 (0)