|
6 | 6 |
|
7 | 7 | use crate::hir::def_id::DefId; |
8 | 8 | use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; |
9 | | -use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; |
| 9 | +use crate::ty::{self, layout::Size, Ty, TyCtxt, TypeFoldable}; |
10 | 10 | use crate::ty::error::{ExpectedFound, TypeError}; |
11 | | -use crate::mir::interpret::{ConstValue, Scalar}; |
| 11 | +use crate::mir::interpret::{AllocId, ConstValue, Pointer, Scalar}; |
12 | 12 | use std::rc::Rc; |
13 | 13 | use std::iter; |
14 | 14 | use rustc_target::spec::abi; |
@@ -584,7 +584,40 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( |
584 | 584 | // FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment |
585 | 585 | // saying that we're not handling it intentionally. |
586 | 586 |
|
587 | | - // FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`. |
| 587 | + ( |
| 588 | + ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a }, |
| 589 | + ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b }, |
| 590 | + ) => { |
| 591 | + let len_a = end_a - offset_a; |
| 592 | + let len_b = end_b - offset_b; |
| 593 | + let a_bytes = alloc_a |
| 594 | + .get_bytes( |
| 595 | + &tcx, |
| 596 | + // invent a pointer, only the offset is relevant anyway |
| 597 | + Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)), |
| 598 | + Size::from_bytes(len_a as u64), |
| 599 | + ) |
| 600 | + .unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err)); |
| 601 | + |
| 602 | + let b_bytes = alloc_b |
| 603 | + .get_bytes( |
| 604 | + &tcx, |
| 605 | + // invent a pointer, only the offset is relevant anyway |
| 606 | + Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)), |
| 607 | + Size::from_bytes(len_b as u64), |
| 608 | + ) |
| 609 | + .unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err)); |
| 610 | + if a_bytes == b_bytes { |
| 611 | + Ok(tcx.mk_const(ty::Const { |
| 612 | + val: ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a }, |
| 613 | + ty: a.ty, |
| 614 | + })) |
| 615 | + } else { |
| 616 | + Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) |
| 617 | + } |
| 618 | + } |
| 619 | + |
| 620 | + // FIXME(const_generics): handle `ConstValue::ByRef`. |
588 | 621 |
|
589 | 622 | // FIXME(const_generics): this is wrong, as it is a projection |
590 | 623 | (ConstValue::Unevaluated(a_def_id, a_substs), |
|
0 commit comments