|
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