Skip to content

Commit 5545916

Browse files
authored
Unrolled build for rust-lang#136121
Rollup merge of rust-lang#136121 - oli-obk:push-zzvxlynmnqpp, r=estebank Deduplicate operand creation between scalars, non-scalars and string patterns just something that felt duplicated and would make pattern type handling a bit more roundabout.
2 parents 61cc3e5 + d62f885 commit 5545916

File tree

1 file changed

+50
-49
lines changed
  • compiler/rustc_mir_build/src/builder/matches

1 file changed

+50
-49
lines changed

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

+50-49
Original file line numberDiff line numberDiff line change
@@ -141,66 +141,71 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141141
self.cfg.terminate(block, self.source_info(match_start_span), terminator);
142142
}
143143

144-
TestKind::Eq { value, ty } => {
144+
TestKind::Eq { value, mut ty } => {
145145
let tcx = self.tcx;
146146
let success_block = target_block(TestBranch::Success);
147147
let fail_block = target_block(TestBranch::Failure);
148-
if let ty::Adt(def, _) = ty.kind()
149-
&& tcx.is_lang_item(def.did(), LangItem::String)
150-
{
151-
if !tcx.features().string_deref_patterns() {
152-
span_bug!(
148+
149+
let expect_ty = value.ty();
150+
let expect = self.literal_operand(test.span, value);
151+
152+
let mut place = place;
153+
let mut block = block;
154+
match ty.kind() {
155+
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => {
156+
if !tcx.features().string_deref_patterns() {
157+
span_bug!(
158+
test.span,
159+
"matching on `String` went through without enabling string_deref_patterns"
160+
);
161+
}
162+
let re_erased = tcx.lifetimes.re_erased;
163+
let ref_str_ty = Ty::new_imm_ref(tcx, re_erased, tcx.types.str_);
164+
let ref_str = self.temp(ref_str_ty, test.span);
165+
let eq_block = self.cfg.start_new_block();
166+
// `let ref_str: &str = <String as Deref>::deref(&place);`
167+
self.call_deref(
168+
block,
169+
eq_block,
170+
place,
171+
Mutability::Not,
172+
ty,
173+
ref_str,
153174
test.span,
154-
"matching on `String` went through without enabling string_deref_patterns"
155175
);
176+
// Since we generated a `ref_str = <String as Deref>::deref(&place) -> eq_block` terminator,
177+
// we need to add all further statements to `eq_block`.
178+
// Similarly, the normal test code should be generated for the `&str`, instead of the `String`.
179+
block = eq_block;
180+
place = ref_str;
181+
ty = ref_str_ty;
156182
}
157-
let re_erased = tcx.lifetimes.re_erased;
158-
let ref_str_ty = Ty::new_imm_ref(tcx, re_erased, tcx.types.str_);
159-
let ref_str = self.temp(ref_str_ty, test.span);
160-
let eq_block = self.cfg.start_new_block();
161-
// `let ref_str: &str = <String as Deref>::deref(&place);`
162-
self.call_deref(
163-
block,
164-
eq_block,
165-
place,
166-
Mutability::Not,
167-
ty,
168-
ref_str,
169-
test.span,
170-
);
171-
self.non_scalar_compare(
172-
eq_block,
173-
success_block,
174-
fail_block,
175-
source_info,
176-
value,
177-
ref_str,
178-
ref_str_ty,
179-
);
180-
} else if !ty.is_scalar() {
183+
_ => {}
184+
}
185+
186+
if !ty.is_scalar() {
181187
// Use `PartialEq::eq` instead of `BinOp::Eq`
182188
// (the binop can only handle primitives)
183189
self.non_scalar_compare(
184190
block,
185191
success_block,
186192
fail_block,
187193
source_info,
188-
value,
189-
place,
194+
expect,
195+
expect_ty,
196+
Operand::Copy(place),
190197
ty,
191198
);
192199
} else {
193-
assert_eq!(value.ty(), ty);
194-
let expect = self.literal_operand(test.span, value);
195-
let val = Operand::Copy(place);
200+
assert_eq!(expect_ty, ty);
196201
self.compare(
197202
block,
198203
success_block,
199204
fail_block,
200205
source_info,
201206
BinOp::Eq,
202207
expect,
203-
val,
208+
Operand::Copy(place),
204209
);
205210
}
206211
}
@@ -371,12 +376,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
371376
success_block: BasicBlock,
372377
fail_block: BasicBlock,
373378
source_info: SourceInfo,
374-
value: Const<'tcx>,
375-
mut val: Place<'tcx>,
379+
mut expect: Operand<'tcx>,
380+
expect_ty: Ty<'tcx>,
381+
mut val: Operand<'tcx>,
376382
mut ty: Ty<'tcx>,
377383
) {
378-
let mut expect = self.literal_operand(source_info.span, value);
379-
380384
// If we're using `b"..."` as a pattern, we need to insert an
381385
// unsizing coercion, as the byte string has the type `&[u8; N]`.
382386
//
@@ -391,7 +395,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
391395
_ => None,
392396
};
393397
let opt_ref_ty = unsize(ty);
394-
let opt_ref_test_ty = unsize(value.ty());
398+
let opt_ref_test_ty = unsize(expect_ty);
395399
match (opt_ref_ty, opt_ref_test_ty) {
396400
// nothing to do, neither is an array
397401
(None, None) => {}
@@ -410,11 +414,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
410414
PointerCoercion::Unsize,
411415
CoercionSource::Implicit,
412416
),
413-
Operand::Copy(val),
417+
val,
414418
ty,
415419
),
416420
);
417-
val = temp;
421+
val = Operand::Copy(temp);
418422
}
419423
if opt_ref_test_ty.is_some() {
420424
let slice = self.temp(ty, source_info.span);
@@ -470,11 +474,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
470474

471475
const_: method,
472476
})),
473-
args: [Spanned { node: Operand::Copy(val), span: DUMMY_SP }, Spanned {
474-
node: expect,
475-
span: DUMMY_SP,
476-
}]
477-
.into(),
477+
args: [Spanned { node: val, span: DUMMY_SP }, Spanned { node: expect, span: DUMMY_SP }]
478+
.into(),
478479
destination: eq_result,
479480
target: Some(eq_block),
480481
unwind: UnwindAction::Continue,

0 commit comments

Comments
 (0)