Skip to content

Commit 706b27e

Browse files
committed
Add handling for one-sided InferVar
1 parent f7b0ed0 commit 706b27e

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

src/librustc/infer/combine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
167167
}
168168
}
169169

170-
fn unify_const_variable(&self,
170+
pub fn unify_const_variable(&self,
171171
vid_is_expected: bool,
172172
vid: ty::ConstVid<'tcx>,
173173
val: &'tcx Const<'tcx>)

src/librustc/infer/equate.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,29 +112,30 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
112112

113113
fn consts(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>)
114114
-> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
115-
// TODO(const_generics): missing handling for when only one side is an InferVar
116115
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
117116
if a == b { return Ok(a); }
118117

119118
let infcx = self.fields.infcx;
120119
let a = replace_const_if_possible(infcx.const_unification_table.borrow_mut(), a);
121120
let b = replace_const_if_possible(infcx.const_unification_table.borrow_mut(), b);
121+
let a_is_expected = self.a_is_expected();
122122
match (a.val, b.val) {
123123
(ConstValue::Infer(InferConst::Var(a_vid)),
124124
ConstValue::Infer(InferConst::Var(b_vid))) => {
125-
let a_is_expected = self.a_is_expected();
126125
infcx.const_unification_table
127126
.borrow_mut()
128127
.unify_var_var(a_vid, b_vid)
129128
.map_err(|e| const_unification_error(a_is_expected, e))?;
130129
Ok(a)
131130
}
132131

133-
(ConstValue::Infer(InferConst::Var(_)), _) => {
132+
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
133+
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
134134
Ok(a)
135135
}
136136

137-
(_, ConstValue::Infer(InferConst::Var(_))) => {
137+
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
138+
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
138139
Ok(a)
139140
}
140141

@@ -153,5 +154,3 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
153154
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
154155
}
155156
}
156-
157-

src/librustc/infer/sub.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
146146

147147
fn consts(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>)
148148
-> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
149-
// TODO(const_generics): missing handling for when only one side is an InferVar
150149
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
151150
if a == b { return Ok(a); }
152151

@@ -156,19 +155,24 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
156155

157156
// Consts can only be equal or unequal to each other: there's no subtyping
158157
// relation, so we're just going to perform equating here instead.
158+
let a_is_expected = self.a_is_expected();
159159
match (a.val, b.val) {
160160
(ConstValue::Infer(InferConst::Var(a_vid)),
161161
ConstValue::Infer(InferConst::Var(b_vid))) => {
162-
let a_is_expected = self.a_is_expected();
163162
infcx.const_unification_table
164163
.borrow_mut()
165164
.unify_var_var(a_vid, b_vid)
166165
.map_err(|e| const_unification_error(a_is_expected, e))?;
167166
Ok(a)
168167
}
169168

170-
(ConstValue::Infer(InferConst::Var(_)), _) |
171-
(_, ConstValue::Infer(InferConst::Var(_))) => {
169+
(ConstValue::Infer(InferConst::Var(a_id)), _) => {
170+
self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
171+
Ok(a)
172+
}
173+
174+
(_, ConstValue::Infer(InferConst::Var(b_id))) => {
175+
self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
172176
Ok(a)
173177
}
174178

0 commit comments

Comments
 (0)