Skip to content

Commit afd1c60

Browse files
authored
Rollup merge of #64679 - skinny121:const-infer, r=varkor
Infer consts more consistently Moved some duplicated logic in `TypeRelation` methods into `super_combined_consts`. Before some `TypeRelation`s like `Lub` wasn't using `replace_if_possible`, meaning some inference types were staying around longer than they should be. Fixes #64519 r? @varkor
2 parents ee2012c + 3f2855e commit afd1c60

File tree

7 files changed

+42
-86
lines changed

7 files changed

+42
-86
lines changed

src/librustc/infer/combine.rs

+7
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use super::sub::Sub;
3030
use super::type_variable::TypeVariableValue;
3131
use super::unify_key::{ConstVarValue, ConstVariableValue};
3232
use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
33+
use super::unify_key::replace_if_possible;
3334

3435
use crate::hir::def_id::DefId;
3536
use crate::mir::interpret::ConstValue;
@@ -127,6 +128,12 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
127128
where
128129
R: TypeRelation<'tcx>,
129130
{
131+
debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
132+
if a == b { return Ok(a); }
133+
134+
let a = replace_if_possible(self.const_unification_table.borrow_mut(), a);
135+
let b = replace_if_possible(self.const_unification_table.borrow_mut(), b);
136+
130137
let a_is_expected = relation.a_is_expected();
131138

132139
match (a.val, b.val) {

src/librustc/infer/equate.rs

+3-37
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
use super::combine::{CombineFields, RelationDir, const_unification_error};
1+
use super::combine::{CombineFields, RelationDir};
22
use super::Subtype;
33

44
use crate::hir::def_id::DefId;
55

6-
use crate::ty::{self, Ty, TyCtxt, InferConst};
6+
use crate::ty::{self, Ty, TyCtxt};
77
use crate::ty::TyVar;
88
use crate::ty::subst::SubstsRef;
99
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
10-
use crate::mir::interpret::ConstValue;
11-
use crate::infer::unify_key::replace_if_possible;
1210

1311
/// Ensures `a` is made equal to `b`. Returns `a` on success.
1412
pub struct Equate<'combine, 'infcx, 'tcx> {
@@ -108,39 +106,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
108106
a: &'tcx ty::Const<'tcx>,
109107
b: &'tcx ty::Const<'tcx>,
110108
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
111-
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
112-
if a == b { return Ok(a); }
113-
114-
let infcx = self.fields.infcx;
115-
let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
116-
let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
117-
let a_is_expected = self.a_is_expected();
118-
119-
match (a.val, b.val) {
120-
(ConstValue::Infer(InferConst::Var(a_vid)),
121-
ConstValue::Infer(InferConst::Var(b_vid))) => {
122-
infcx.const_unification_table
123-
.borrow_mut()
124-
.unify_var_var(a_vid, b_vid)
125-
.map_err(|e| const_unification_error(a_is_expected, e))?;
126-
return Ok(a);
127-
}
128-
129-
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
130-
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
131-
return Ok(a);
132-
}
133-
134-
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
135-
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
136-
return Ok(a);
137-
}
138-
139-
_ => {}
140-
}
141-
142-
self.fields.infcx.super_combine_consts(self, a, b)?;
143-
Ok(a)
109+
self.fields.infcx.super_combine_consts(self, a, b)
144110
}
145111

146112
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)

src/librustc/infer/glb.rs

-5
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
6666
a: &'tcx ty::Const<'tcx>,
6767
b: &'tcx ty::Const<'tcx>,
6868
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
69-
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
70-
if a == b {
71-
return Ok(a);
72-
}
73-
7469
self.fields.infcx.super_combine_consts(self, a, b)
7570
}
7671

src/librustc/infer/lub.rs

-5
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
6666
a: &'tcx ty::Const<'tcx>,
6767
b: &'tcx ty::Const<'tcx>,
6868
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
69-
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
70-
if a == b {
71-
return Ok(a);
72-
}
73-
7469
self.fields.infcx.super_combine_consts(self, a, b)
7570
}
7671

src/librustc/infer/sub.rs

+3-39
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
use super::SubregionOrigin;
2-
use super::combine::{CombineFields, RelationDir, const_unification_error};
2+
use super::combine::{CombineFields, RelationDir};
33

44
use crate::traits::Obligation;
5-
use crate::ty::{self, Ty, TyCtxt, InferConst};
5+
use crate::ty::{self, Ty, TyCtxt};
66
use crate::ty::TyVar;
77
use crate::ty::fold::TypeFoldable;
88
use crate::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
9-
use crate::infer::unify_key::replace_if_possible;
10-
use crate::mir::interpret::ConstValue;
119
use std::mem;
1210

1311
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
@@ -142,41 +140,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
142140
a: &'tcx ty::Const<'tcx>,
143141
b: &'tcx ty::Const<'tcx>,
144142
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
145-
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
146-
if a == b { return Ok(a); }
147-
148-
let infcx = self.fields.infcx;
149-
let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
150-
let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
151-
152-
// Consts can only be equal or unequal to each other: there's no subtyping
153-
// relation, so we're just going to perform equating here instead.
154-
let a_is_expected = self.a_is_expected();
155-
match (a.val, b.val) {
156-
(ConstValue::Infer(InferConst::Var(a_vid)),
157-
ConstValue::Infer(InferConst::Var(b_vid))) => {
158-
infcx.const_unification_table
159-
.borrow_mut()
160-
.unify_var_var(a_vid, b_vid)
161-
.map_err(|e| const_unification_error(a_is_expected, e))?;
162-
return Ok(a);
163-
}
164-
165-
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
166-
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
167-
return Ok(a);
168-
}
169-
170-
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
171-
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
172-
return Ok(a);
173-
}
174-
175-
_ => {}
176-
}
177-
178-
self.fields.infcx.super_combine_consts(self, a, b)?;
179-
Ok(a)
143+
self.fields.infcx.super_combine_consts(self, a, b)
180144
}
181145

182146
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
5+
6+
struct Foo<const D: usize> {
7+
state: Option<[u8; D]>,
8+
}
9+
10+
impl<const D: usize> Iterator for Foo<{D}> {
11+
type Item = [u8; D];
12+
fn next(&mut self) -> Option<Self::Item> {
13+
if true {
14+
return Some(self.state.unwrap().clone());
15+
} else {
16+
return Some(self.state.unwrap().clone());
17+
}
18+
}
19+
}
20+
21+
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-64519.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)