Skip to content

Commit b2b3579

Browse files
authored
Rollup merge of #65696 - varkor:nll-chalk-const-generics-issue, r=eddyb
Fix an issue with const inference variables sticking around under Chalk + NLL Fixes #65675. Fixes #62579. r? @eddyb cc @LukasKalbertodt @Skinny121
2 parents ba9a9eb + 624e34a commit b2b3579

File tree

6 files changed

+98
-30
lines changed

6 files changed

+98
-30
lines changed

src/librustc/infer/combine.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
494494
if sub_vid == self.for_vid_sub_root {
495495
// If sub-roots are equal, then `for_vid` and
496496
// `vid` are related via subtyping.
497-
return Err(TypeError::CyclicTy(self.root_ty));
497+
Err(TypeError::CyclicTy(self.root_ty))
498498
} else {
499499
match variables.probe(vid) {
500500
TypeVariableValue::Known { value: u } => {
@@ -527,7 +527,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
527527
let u = self.tcx().mk_ty_var(new_var_id);
528528
debug!("generalize: replacing original vid={:?} with new={:?}",
529529
vid, u);
530-
return Ok(u);
530+
Ok(u)
531531
}
532532
}
533533
}
@@ -602,19 +602,26 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
602602
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
603603
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
604604

605-
match c {
606-
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
605+
match c.val {
606+
ConstValue::Infer(InferConst::Var(vid)) => {
607607
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
608-
match variable_table.probe_value(*vid).val.known() {
609-
Some(u) => {
610-
self.relate(&u, &u)
608+
let var_value = variable_table.probe_value(vid);
609+
match var_value.val {
610+
ConstVariableValue::Known { value: u } => self.relate(&u, &u),
611+
ConstVariableValue::Unknown { universe } => {
612+
if self.for_universe.can_name(universe) {
613+
Ok(c)
614+
} else {
615+
let new_var_id = variable_table.new_key(ConstVarValue {
616+
origin: var_value.origin,
617+
val: ConstVariableValue::Unknown { universe: self.for_universe },
618+
});
619+
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
620+
}
611621
}
612-
None => Ok(c),
613622
}
614623
}
615-
_ => {
616-
relate::super_relate_consts(self, c, c)
617-
}
624+
_ => relate::super_relate_consts(self, c, c),
618625
}
619626
}
620627
}

src/librustc/infer/nll_relate/mod.rs

+39-19
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use crate::ty::error::TypeError;
2727
use crate::ty::fold::{TypeFoldable, TypeVisitor};
2828
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
2929
use crate::ty::subst::GenericArg;
30-
use crate::ty::{self, Ty, TyCtxt};
30+
use crate::ty::{self, Ty, TyCtxt, InferConst};
31+
use crate::infer::{ConstVariableValue, ConstVarValue};
3132
use crate::mir::interpret::ConstValue;
3233
use rustc_data_structures::fx::FxHashMap;
3334
use std::fmt::Debug;
@@ -324,7 +325,7 @@ where
324325
let vid = pair.vid();
325326
let value_ty = pair.value_ty();
326327

327-
// FIXME -- this logic assumes invariance, but that is wrong.
328+
// FIXME(invariance) -- this logic assumes invariance, but that is wrong.
328329
// This only presently applies to chalk integration, as NLL
329330
// doesn't permit type variables to appear on both sides (and
330331
// doesn't use lazy norm).
@@ -616,15 +617,21 @@ where
616617
fn consts(
617618
&mut self,
618619
a: &'tcx ty::Const<'tcx>,
619-
b: &'tcx ty::Const<'tcx>,
620+
mut b: &'tcx ty::Const<'tcx>,
620621
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
621-
if let ty::Const { val: ConstValue::Bound(..), .. } = a {
622-
// FIXME(const_generics): I'm unsure how this branch should actually be handled,
623-
// so this is probably not correct.
624-
self.infcx.super_combine_consts(self, a, b)
625-
} else {
626-
debug!("consts(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance);
627-
relate::super_relate_consts(self, a, b)
622+
let a = self.infcx.shallow_resolve(a);
623+
624+
if !D::forbid_inference_vars() {
625+
b = self.infcx.shallow_resolve(b);
626+
}
627+
628+
match b.val {
629+
ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
630+
// Forbid inference variables in the RHS.
631+
bug!("unexpected inference var {:?}", b)
632+
}
633+
// FIXME(invariance): see the related FIXME above.
634+
_ => self.infcx.super_combine_consts(self, a, b)
628635
}
629636
}
630637

@@ -991,15 +998,28 @@ where
991998
a: &'tcx ty::Const<'tcx>,
992999
_: &'tcx ty::Const<'tcx>,
9931000
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
994-
debug!("TypeGeneralizer::consts(a={:?})", a);
995-
996-
if let ty::Const { val: ConstValue::Bound(..), .. } = a {
997-
bug!(
998-
"unexpected inference variable encountered in NLL generalization: {:?}",
999-
a
1000-
);
1001-
} else {
1002-
relate::super_relate_consts(self, a, a)
1001+
match a.val {
1002+
ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
1003+
bug!(
1004+
"unexpected inference variable encountered in NLL generalization: {:?}",
1005+
a
1006+
);
1007+
}
1008+
ConstValue::Infer(InferConst::Var(vid)) => {
1009+
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
1010+
let var_value = variable_table.probe_value(vid);
1011+
match var_value.val.known() {
1012+
Some(u) => self.relate(&u, &u),
1013+
None => {
1014+
let new_var_id = variable_table.new_key(ConstVarValue {
1015+
origin: var_value.origin,
1016+
val: ConstVariableValue::Unknown { universe: self.universe },
1017+
});
1018+
Ok(self.tcx().mk_const_var(new_var_id, a.ty))
1019+
}
1020+
}
1021+
}
1022+
_ => relate::super_relate_consts(self, a, a),
10031023
}
10041024
}
10051025

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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+
#[derive(PartialEq, Eq)]
7+
struct NoMatch;
8+
9+
fn foo<const T: NoMatch>() -> bool {
10+
true
11+
}
12+
13+
fn main() {
14+
foo::<{NoMatch}>();
15+
}
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/issue-62579-no-match.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// run-pass
2+
// compile-flags: -Z chalk
3+
4+
#![feature(const_generics)]
5+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
6+
7+
pub struct Foo<T, const N: usize>([T; N]);
8+
impl<T, const N: usize> Foo<T, {N}> {}
9+
10+
fn main() {}
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/issue-65675.rs:4:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+

0 commit comments

Comments
 (0)