Skip to content

Commit 100bee6

Browse files
authored
Rollup merge of rust-lang#71018 - lcnr:custom-const-param, r=eddyb
handle ConstValue::ByRef in relate fixes rust-lang#68615 r? @eddyb
2 parents fd61d06 + a08bccb commit 100bee6

File tree

7 files changed

+90
-3
lines changed

7 files changed

+90
-3
lines changed

src/librustc_infer/infer/at.rs

-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
186186
impl<'a, 'tcx> Trace<'a, 'tcx> {
187187
/// Makes `a <: b` where `a` may or may not be expected (if
188188
/// `a_is_expected` is true, then `a` is expected).
189-
/// Makes `expected <: actual`.
190189
pub fn sub<T>(self, a: &T, b: &T) -> InferResult<'tcx, ()>
191190
where
192191
T: Relate<'tcx>,

src/librustc_middle/ty/relate.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
1111
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
1212
use rustc_hir as ast;
1313
use rustc_hir::def_id::DefId;
14+
use rustc_span::DUMMY_SP;
1415
use rustc_target::spec::abi;
1516
use std::iter;
1617
use std::rc::Rc;
@@ -507,6 +508,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
507508
a: &'tcx ty::Const<'tcx>,
508509
b: &'tcx ty::Const<'tcx>,
509510
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
511+
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
510512
let tcx = relation.tcx();
511513

512514
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
@@ -561,7 +563,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
561563
}
562564
}
563565

564-
(a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
566+
(ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
565567
let a_bytes = get_slice_bytes(&tcx, a_val);
566568
let b_bytes = get_slice_bytes(&tcx, b_val);
567569
if a_bytes == b_bytes {
@@ -571,7 +573,37 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
571573
}
572574
}
573575

574-
// FIXME(const_generics): handle `ConstValue::ByRef`.
576+
(ConstValue::ByRef { .. }, ConstValue::ByRef { .. }) => {
577+
match a.ty.kind {
578+
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
579+
let a_destructured = tcx.destructure_const(relation.param_env().and(a));
580+
let b_destructured = tcx.destructure_const(relation.param_env().and(b));
581+
582+
// Both the variant and each field have to be equal.
583+
if a_destructured.variant == b_destructured.variant {
584+
for (a_field, b_field) in
585+
a_destructured.fields.iter().zip(b_destructured.fields.iter())
586+
{
587+
relation.consts(a_field, b_field)?;
588+
}
589+
590+
Ok(a_val)
591+
} else {
592+
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
593+
}
594+
}
595+
// FIXME(const_generics): There are probably some `TyKind`s
596+
// which should be handled here.
597+
_ => {
598+
tcx.sess.delay_span_bug(
599+
DUMMY_SP,
600+
&format!("unexpected consts: a: {:?}, b: {:?}", a, b),
601+
);
602+
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
603+
}
604+
}
605+
}
606+
575607
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
576608
};
577609

src/librustc_typeck/check/coercion.rs

+3
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ fn coerce_mutbls<'tcx>(
107107
}
108108
}
109109

110+
/// Do not require any adjustments, i.e. coerce `x -> x`.
110111
fn identity(_: Ty<'_>) -> Vec<Adjustment<'_>> {
111112
vec![]
112113
}
@@ -115,6 +116,7 @@ fn simple(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>
115116
move |target| vec![Adjustment { kind, target }]
116117
}
117118

119+
/// This always returns `Ok(...)`.
118120
fn success<'tcx>(
119121
adj: Vec<Adjustment<'tcx>>,
120122
target: Ty<'tcx>,
@@ -133,6 +135,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
133135
}
134136

135137
pub fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
138+
debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
136139
self.commit_if_ok(|_| {
137140
if self.use_lub {
138141
self.at(&self.cause, self.fcx.param_env).lub(b, a)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
struct Const<const V: [usize; 1]> {}
5+
6+
fn main() {
7+
let mut x = Const::<{ [3] }> {};
8+
x = Const::<{ [4] }> {};
9+
//~^ ERROR mismatched types
10+
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/different_byref.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/different_byref.rs:8:9
11+
|
12+
LL | x = Const::<{ [4] }> {};
13+
| ^^^^^^^^^^^^^^^^^^^ expected `3usize`, found `4usize`
14+
|
15+
= note: expected struct `Const<[3usize]>`
16+
found struct `Const<[4usize]>`
17+
18+
error: aborting due to previous error; 1 warning emitted
19+
20+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// check-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
struct Const<const V: [usize; 0]> {}
6+
type MyConst = Const<{ [] }>;
7+
8+
fn main() {
9+
let _x = Const::<{ [] }> {};
10+
let _y = MyConst {};
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// check-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
struct Foo<const V: [usize; 0] > {}
6+
7+
type MyFoo = Foo<{ [] }>;
8+
9+
fn main() {
10+
let _ = Foo::<{ [] }> {};
11+
}

0 commit comments

Comments
 (0)