Skip to content

Commit 5e8a89b

Browse files
committed
Reduce the duplication in the relation logic for constants
1 parent 4d917fa commit 5e8a89b

File tree

1 file changed

+45
-67
lines changed

1 file changed

+45
-67
lines changed

compiler/rustc_middle/src/ty/relate.rs

Lines changed: 45 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
//! types or regions but can be other things. Examples of type relations are
55
//! subtyping, type equality, etc.
66
7-
use crate::mir::interpret::{get_slice_bytes, ConstValue};
7+
use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar};
88
use crate::ty::error::{ExpectedFound, TypeError};
99
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
1010
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
1111
use rustc_hir as ast;
1212
use rustc_hir::def_id::DefId;
13-
use rustc_span::DUMMY_SP;
1413
use rustc_target::spec::abi;
1514
use std::iter;
1615

@@ -513,93 +512,71 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
513512
// Currently, the values that can be unified are primitive types,
514513
// and those that derive both `PartialEq` and `Eq`, corresponding
515514
// to structural-match types.
516-
match (a.val, b.val) {
515+
let is_match = match (a.val, b.val) {
517516
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
518517
// The caller should handle these cases!
519518
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
520519
}
521520

522-
(ty::ConstKind::Error(_), _) => Ok(a),
523-
(_, ty::ConstKind::Error(_)) => Ok(b),
521+
(ty::ConstKind::Error(_), _) => return Ok(a),
522+
(_, ty::ConstKind::Error(_)) => return Ok(b),
524523

525-
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
526-
return Ok(a);
527-
}
528-
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) if p1 == p2 => {
529-
return Ok(a);
530-
}
524+
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) => a_p.index == b_p.index,
525+
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
531526
(ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => {
532527
match (a_val, b_val) {
533-
(ConstValue::Scalar(a_val), ConstValue::Scalar(b_val)) => {
534-
if a_val == b_val {
535-
Ok(a)
536-
} else if let ty::FnPtr(_) = a.ty.kind() {
537-
let a_instance = tcx.global_alloc(a_val.assert_ptr().alloc_id).unwrap_fn();
538-
let b_instance = tcx.global_alloc(b_val.assert_ptr().alloc_id).unwrap_fn();
539-
if a_instance == b_instance {
540-
Ok(a)
541-
} else {
542-
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
528+
(
529+
ConstValue::Scalar(Scalar::Int(a_val)),
530+
ConstValue::Scalar(Scalar::Int(b_val)),
531+
) => a_val == b_val,
532+
(
533+
ConstValue::Scalar(Scalar::Ptr(a_val)),
534+
ConstValue::Scalar(Scalar::Ptr(b_val)),
535+
) => {
536+
a_val == b_val
537+
|| match (
538+
tcx.global_alloc(a_val.alloc_id),
539+
tcx.global_alloc(b_val.alloc_id),
540+
) {
541+
(
542+
GlobalAlloc::Function(a_instance),
543+
GlobalAlloc::Function(b_instance),
544+
) => a_instance == b_instance,
545+
_ => false,
543546
}
544-
} else {
545-
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
546-
}
547547
}
548548

549549
(ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
550-
let a_bytes = get_slice_bytes(&tcx, a_val);
551-
let b_bytes = get_slice_bytes(&tcx, b_val);
552-
if a_bytes == b_bytes {
553-
Ok(a)
554-
} else {
555-
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
556-
}
550+
get_slice_bytes(&tcx, a_val) == get_slice_bytes(&tcx, b_val)
557551
}
558552

559553
(ConstValue::ByRef { .. }, ConstValue::ByRef { .. }) => {
560-
match a.ty.kind() {
561-
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
562-
let a_destructured = tcx.destructure_const(relation.param_env().and(a));
563-
let b_destructured = tcx.destructure_const(relation.param_env().and(b));
564-
565-
// Both the variant and each field have to be equal.
566-
if a_destructured.variant == b_destructured.variant {
567-
for (a_field, b_field) in
568-
a_destructured.fields.iter().zip(b_destructured.fields.iter())
569-
{
570-
relation.consts(a_field, b_field)?;
571-
}
572-
573-
Ok(a)
574-
} else {
575-
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
576-
}
577-
}
578-
// FIXME(const_generics): There are probably some `TyKind`s
579-
// which should be handled here.
580-
_ => {
581-
tcx.sess.delay_span_bug(
582-
DUMMY_SP,
583-
&format!("unexpected consts: a: {:?}, b: {:?}", a, b),
584-
);
585-
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
554+
let a_destructured = tcx.destructure_const(relation.param_env().and(a));
555+
let b_destructured = tcx.destructure_const(relation.param_env().and(b));
556+
557+
// Both the variant and each field have to be equal.
558+
if a_destructured.variant == b_destructured.variant {
559+
for (a_field, b_field) in
560+
a_destructured.fields.iter().zip(b_destructured.fields.iter())
561+
{
562+
relation.consts(a_field, b_field)?;
586563
}
564+
565+
true
566+
} else {
567+
false
587568
}
588569
}
589570

590-
_ => Err(TypeError::ConstMismatch(expected_found(relation, a, b))),
571+
_ => false,
591572
}
592573
}
593574

594575
(
595576
ty::ConstKind::Unevaluated(a_def, a_substs, None),
596577
ty::ConstKind::Unevaluated(b_def, b_substs, None),
597578
) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => {
598-
if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) {
599-
Ok(a)
600-
} else {
601-
Err(TypeError::ConstMismatch(expected_found(relation, a, b)))
602-
}
579+
tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
603580
}
604581

605582
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
@@ -611,13 +588,14 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
611588
) if a_def == b_def && a_promoted == b_promoted => {
612589
let substs =
613590
relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
614-
Ok(tcx.mk_const(ty::Const {
591+
return Ok(tcx.mk_const(ty::Const {
615592
val: ty::ConstKind::Unevaluated(a_def, substs, a_promoted),
616593
ty: a.ty,
617-
}))
594+
}));
618595
}
619-
_ => Err(TypeError::ConstMismatch(expected_found(relation, a, b))),
620-
}
596+
_ => false,
597+
};
598+
if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) }
621599
}
622600

623601
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>> {

0 commit comments

Comments
 (0)