Skip to content

Commit 3a435f9

Browse files
committed
working autocoercion
1 parent cbb3e19 commit 3a435f9

File tree

2 files changed

+54
-48
lines changed

2 files changed

+54
-48
lines changed

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,24 +160,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
160160
let tcx = self.tcx;
161161
tracing::warn!("valtree_to_match_pair: {:?} {:?}", subslice_len, src_pat_ty);
162162

163-
let (const_ty, pat_ty) = match src_pat_ty.kind() {
164-
ty::Slice(_) => {
165-
(Ty::new_imm_ref(
163+
let (const_ty, pat_ty) = match src_pat_ty.kind() {
164+
ty::Slice(_) => (
165+
Ty::new_imm_ref(
166166
tcx,
167167
tcx.lifetimes.re_erased,
168168
Ty::new_array(tcx, elem_ty, subslice_len),
169169
),
170-
Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, Ty::new_slice(tcx, elem_ty)),)
171-
}
172-
ty::Array(_, _) => {
173-
(Ty::new_imm_ref(
170+
Ty::new_slice(tcx, elem_ty),
171+
),
172+
ty::Array(_, _) => (
173+
Ty::new_imm_ref(
174174
tcx,
175175
tcx.lifetimes.re_erased,
176176
Ty::new_array(tcx, elem_ty, subslice_len),
177177
),
178-
Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, Ty::new_array(tcx, elem_ty, subslice_len)),)
179-
}
180-
_ => todo!()
178+
Ty::new_array(tcx, elem_ty, subslice_len),
179+
),
180+
_ => todo!(),
181181
};
182182

183183
let r#const = ty::Const::new(tcx, ty::ConstKind::Value(const_ty, valtree));

compiler/rustc_mir_build/src/builder/matches/test.rs

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::cmp::Ordering;
1010
use rustc_data_structures::fx::FxIndexMap;
1111
use rustc_hir::{LangItem, RangeEnd};
1212
use rustc_middle::mir::*;
13+
use rustc_middle::ty::adjustment::PointerCoercion;
1314
use rustc_middle::ty::util::IntTypeExt;
1415
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt};
1516
use rustc_middle::{bug, span_bug};
@@ -374,53 +375,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
374375
mut val: Place<'tcx>,
375376
mut ty: Ty<'tcx>,
376377
) {
377-
let expect_ty = value.ty();
378+
let mut expect_ty = value.ty();
378379
let expect_op = self.literal_operand(source_info.span, value);
379380
let mut expect = self.temp(value.ty(), source_info.span);
380-
self.cfg.push_assign(
381-
block,
382-
source_info,
383-
expect,
384-
Rvalue::Use(expect_op),
385-
);
381+
self.cfg.push_assign(block, source_info, expect, Rvalue::Use(expect_op));
386382

387-
match ty.kind() {
388-
ty::Ref(_, inner_ty, _) if inner_ty.is_slice() => {
389-
let ref_ty = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, ty);
383+
let mut normalize_depth = |mut ty: Ty<'tcx>, mut val: Place<'tcx>| {
384+
if !ty.is_ref() {
385+
ty = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, ty);
390386
let temp = self.temp(ty, source_info.span);
391387
self.cfg.push_assign(
392388
block,
393389
source_info,
394390
temp,
395391
Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, val),
396392
);
397-
ty = ref_ty;
398393
val = temp;
399-
tracing::warn!("slice ty sig: {:?}", ty);
400-
}
401-
ty::Ref(_, inner_ty, _) if inner_ty.is_array() => {
402-
let ref_ty = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, ty);
403-
let temp = self.temp(ref_ty, source_info.span);
404-
self.cfg.push_assign(
405-
block,
406-
source_info,
407-
temp,
408-
Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, val),
409-
);
410-
411-
ty = ref_ty;
412-
val = temp;
413-
tracing::warn!("arr ty sig: {:?}", ty);
414-
}
415-
ty::Ref(_, inner_ty, _) if inner_ty.is_str() => {
416-
// nothing yet
417-
}
418-
_ => todo!("not yet, ty: {:?}", ty),
419-
}
420-
421-
let mut normalize_depth = |mut ty: Ty<'tcx>, mut val: Place<'tcx>| {
422-
if !ty.is_ref() {
423-
panic!("not a reference?");
394+
return (ty, val);
424395
}
425396

426397
loop {
@@ -438,15 +409,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
438409
tracing::warn!("from {:?} to {:?}", val, temp);
439410
val = temp;
440411
}
441-
_=> break,
412+
_ => break,
442413
}
443414
}
444415

445416
(ty, val)
446417
};
447418

448419
(ty, val) = normalize_depth(ty, val);
449-
(_, expect) = normalize_depth(expect_ty, expect);
420+
(expect_ty, expect) = normalize_depth(expect_ty, expect);
421+
422+
let mut coerce = |mut ty: Ty<'tcx>, mut place: Place<'tcx>, elem_ty: Ty<'tcx>| {
423+
assert!(ty.is_ref() && ty.peel_refs().is_array());
424+
let ref_ty = Ty::new_imm_ref(
425+
self.tcx,
426+
self.tcx.lifetimes.re_erased,
427+
Ty::new_slice(self.tcx, elem_ty),
428+
);
429+
430+
let ref_val = self.temp(ref_ty, source_info.span);
431+
self.cfg.push_assign(
432+
block,
433+
source_info,
434+
ref_val,
435+
Rvalue::Cast(
436+
CastKind::PointerCoercion(PointerCoercion::Unsize, CoercionSource::Implicit),
437+
Operand::Copy(place),
438+
ref_ty,
439+
),
440+
);
441+
442+
ty = ref_ty;
443+
place = ref_val;
444+
(ty, place)
445+
};
446+
447+
match (ty.peel_refs().kind(), expect_ty.peel_refs().kind()) {
448+
(ty::Slice(_), ty::Array(elem_ty, _)) => {
449+
(_, expect) = coerce(expect_ty, expect, *elem_ty);
450+
}
451+
(ty::Array(elem_ty, _), ty::Slice(_)) => {
452+
(ty, val) = coerce(ty, val, *elem_ty);
453+
}
454+
_ => (),
455+
}
450456

451457
// Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping
452458
// reference: we can only compare two `&T`, and then compare_ty will be `T`.

0 commit comments

Comments
 (0)