Skip to content

Commit 22b87a5

Browse files
committed
Add support for relating slices in super_relate_consts.
1 parent 084beb8 commit 22b87a5

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

src/librustc/ty/relate.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
77
use crate::hir::def_id::DefId;
88
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};
1010
use crate::ty::error::{ExpectedFound, TypeError};
11-
use crate::mir::interpret::{ConstValue, Scalar};
11+
use crate::mir::interpret::{AllocId, ConstValue, Pointer, Scalar};
1212
use std::rc::Rc;
1313
use std::iter;
1414
use rustc_target::spec::abi;
@@ -584,7 +584,40 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
584584
// FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
585585
// saying that we're not handling it intentionally.
586586

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`.
588621

589622
// FIXME(const_generics): this is wrong, as it is a projection
590623
(ConstValue::Unevaluated(a_def_id, a_substs),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// run-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
5+
6+
pub fn function_with_str<const STRING: &'static str>() -> &'static str {
7+
STRING
8+
}
9+
10+
pub fn main() {
11+
assert_eq!(function_with_str::<"Rust">(), "Rust");
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/str-const-param.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+

0 commit comments

Comments
 (0)