diff options
| author | Bastian Kauschke <bastian_kauschke@hotmail.de> | 2020-04-11 18:05:02 +0200 |
|---|---|---|
| committer | Bastian Kauschke <bastian_kauschke@hotmail.de> | 2020-04-30 17:44:24 +0200 |
| commit | a08bccb3c142fb98193eed202dbdde85386dd91a (patch) | |
| tree | e7c1525dc6781a31ce0b5f44c654ecd6f3a28742 | |
| parent | 01b3637f6e9c01c003f8d9f9bba6d4a6e3c780a9 (diff) | |
| download | rust-a08bccb3c142fb98193eed202dbdde85386dd91a.tar.gz rust-a08bccb3c142fb98193eed202dbdde85386dd91a.zip | |
handle ByRef in relate
| -rw-r--r-- | src/librustc_middle/ty/relate.rs | 36 | ||||
| -rw-r--r-- | src/test/ui/const-generics/different_byref.rs | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/different_byref.stderr | 20 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68615-adt.rs | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68615-array.rs | 11 |
5 files changed, 87 insertions, 2 deletions
diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index f4f0b6c41b9..4bfa46367d0 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -11,6 +11,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_hir as ast; use rustc_hir::def_id::DefId; +use rustc_span::DUMMY_SP; use rustc_target::spec::abi; use std::iter; use std::rc::Rc; @@ -507,6 +508,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { + debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); let tcx = relation.tcx(); let eagerly_eval = |x: &'tcx ty::Const<'tcx>| { @@ -561,7 +563,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( } } - (a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => { + (ConstValue::Slice { .. }, ConstValue::Slice { .. }) => { let a_bytes = get_slice_bytes(&tcx, a_val); let b_bytes = get_slice_bytes(&tcx, b_val); if a_bytes == b_bytes { @@ -571,7 +573,37 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( } } - // FIXME(const_generics): handle `ConstValue::ByRef`. + (ConstValue::ByRef { .. }, ConstValue::ByRef { .. }) => { + match a.ty.kind { + ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => { + let a_destructured = tcx.destructure_const(relation.param_env().and(a)); + let b_destructured = tcx.destructure_const(relation.param_env().and(b)); + + // Both the variant and each field have to be equal. + if a_destructured.variant == b_destructured.variant { + for (a_field, b_field) in + a_destructured.fields.iter().zip(b_destructured.fields.iter()) + { + relation.consts(a_field, b_field)?; + } + + Ok(a_val) + } else { + Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) + } + } + // FIXME(const_generics): There are probably some `TyKind`s + // which should be handled here. + _ => { + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!("unexpected consts: a: {:?}, b: {:?}", a, b), + ); + Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) + } + } + } + _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), }; diff --git a/src/test/ui/const-generics/different_byref.rs b/src/test/ui/const-generics/different_byref.rs new file mode 100644 index 00000000000..c52a5b8061d --- /dev/null +++ b/src/test/ui/const-generics/different_byref.rs @@ -0,0 +1,11 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +struct Const<const V: [usize; 1]> {} + +fn main() { + let mut x = Const::<{ [3] }> {}; + x = Const::<{ [4] }> {}; + //~^ ERROR mismatched types + +} diff --git a/src/test/ui/const-generics/different_byref.stderr b/src/test/ui/const-generics/different_byref.stderr new file mode 100644 index 00000000000..9ea2aace89a --- /dev/null +++ b/src/test/ui/const-generics/different_byref.stderr @@ -0,0 +1,20 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/different_byref.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0308]: mismatched types + --> $DIR/different_byref.rs:8:9 + | +LL | x = Const::<{ [4] }> {}; + | ^^^^^^^^^^^^^^^^^^^ expected `3usize`, found `4usize` + | + = note: expected struct `Const<[3usize]>` + found struct `Const<[4usize]>` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.rs b/src/test/ui/const-generics/issues/issue-68615-adt.rs new file mode 100644 index 00000000000..140bb28ec5a --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-68615-adt.rs @@ -0,0 +1,11 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +struct Const<const V: [usize; 0]> {} +type MyConst = Const<{ [] }>; + +fn main() { + let _x = Const::<{ [] }> {}; + let _y = MyConst {}; +} diff --git a/src/test/ui/const-generics/issues/issue-68615-array.rs b/src/test/ui/const-generics/issues/issue-68615-array.rs new file mode 100644 index 00000000000..c384bc1e36d --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-68615-array.rs @@ -0,0 +1,11 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +struct Foo<const V: [usize; 0] > {} + +type MyFoo = Foo<{ [] }>; + +fn main() { + let _ = Foo::<{ [] }> {}; +} |
