diff options
| author | ben <benlewisj@gmail.com> | 2019-09-27 19:43:46 +1200 |
|---|---|---|
| committer | ben <benlewisj@gmail.com> | 2019-09-28 10:05:37 +1200 |
| commit | 22b87a5515b73bfc60a0d1da533d7aeae4a61c21 (patch) | |
| tree | 24def8f39e0d5438c4f3aa8a138c33f8b1427e1b /src | |
| parent | 084beb83e0e87d673d5fabc844d28e8e8ae2ab4c (diff) | |
Add support for relating slices in `super_relate_consts`.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/ty/relate.rs | 39 | ||||
| -rw-r--r-- | src/test/ui/const-generics/str-const-param.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/const-generics/str-const-param.stderr | 8 |
3 files changed, 56 insertions, 3 deletions
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 2af6963f712..8eab939cf86 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -6,9 +6,9 @@ use crate::hir::def_id::DefId; use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, layout::Size, Ty, TyCtxt, TypeFoldable}; use crate::ty::error::{ExpectedFound, TypeError}; -use crate::mir::interpret::{ConstValue, Scalar}; +use crate::mir::interpret::{AllocId, ConstValue, Pointer, Scalar}; use std::rc::Rc; use std::iter; use rustc_target::spec::abi; @@ -584,7 +584,40 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( // FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment // saying that we're not handling it intentionally. - // FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`. + ( + ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a }, + ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b }, + ) => { + let len_a = end_a - offset_a; + let len_b = end_b - offset_b; + let a_bytes = alloc_a + .get_bytes( + &tcx, + // invent a pointer, only the offset is relevant anyway + Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)), + Size::from_bytes(len_a as u64), + ) + .unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err)); + + let b_bytes = alloc_b + .get_bytes( + &tcx, + // invent a pointer, only the offset is relevant anyway + Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)), + Size::from_bytes(len_b as u64), + ) + .unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err)); + if a_bytes == b_bytes { + Ok(tcx.mk_const(ty::Const { + val: ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a }, + ty: a.ty, + })) + } else { + Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) + } + } + + // FIXME(const_generics): handle `ConstValue::ByRef`. // FIXME(const_generics): this is wrong, as it is a projection (ConstValue::Unevaluated(a_def_id, a_substs), diff --git a/src/test/ui/const-generics/str-const-param.rs b/src/test/ui/const-generics/str-const-param.rs new file mode 100644 index 00000000000..a455ca994b8 --- /dev/null +++ b/src/test/ui/const-generics/str-const-param.rs @@ -0,0 +1,12 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +pub fn function_with_str<const STRING: &'static str>() -> &'static str { + STRING +} + +pub fn main() { + assert_eq!(function_with_str::<"Rust">(), "Rust"); +} diff --git a/src/test/ui/const-generics/str-const-param.stderr b/src/test/ui/const-generics/str-const-param.stderr new file mode 100644 index 00000000000..9b71b5b586e --- /dev/null +++ b/src/test/ui/const-generics/str-const-param.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/str-const-param.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + |
