Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1bfc732

Browse files
committed
Store diverging flag for type variables as bitflags
1 parent a97c71f commit 1bfc732

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir-ty/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ doctest = false
1313
cov-mark = "2.0.0-pre.1"
1414
itertools = "0.10.5"
1515
arrayvec = "0.7.2"
16+
bitflags = "1.3.2"
1617
smallvec = "1.10.0"
1718
ena = "0.14.0"
1819
tracing = "0.1.35"

crates/hir-ty/src/infer/unify.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Unification and canonicalization logic.
22
3-
use std::{fmt, mem, sync::Arc};
3+
use std::{fmt, iter, mem, sync::Arc};
44

55
use chalk_ir::{
66
cast::Cast, fold::TypeFoldable, interner::HasInterner, zip::Zip, CanonicalVarKind, FloatTy,
@@ -128,9 +128,11 @@ pub(crate) fn unify(
128128
))
129129
}
130130

131-
#[derive(Copy, Clone, Debug)]
132-
pub(crate) struct TypeVariableData {
133-
diverging: bool,
131+
bitflags::bitflags! {
132+
#[derive(Default)]
133+
pub(crate) struct TypeVariableFlags: u8 {
134+
const DIVERGING = 1 << 0;
135+
}
134136
}
135137

136138
type ChalkInferenceTable = chalk_solve::infer::InferenceTable<Interner>;
@@ -140,14 +142,14 @@ pub(crate) struct InferenceTable<'a> {
140142
pub(crate) db: &'a dyn HirDatabase,
141143
pub(crate) trait_env: Arc<TraitEnvironment>,
142144
var_unification_table: ChalkInferenceTable,
143-
type_variable_table: Vec<TypeVariableData>,
145+
type_variable_table: Vec<TypeVariableFlags>,
144146
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
145147
}
146148

147149
pub(crate) struct InferenceTableSnapshot {
148150
var_table_snapshot: chalk_solve::infer::InferenceSnapshot<Interner>,
149151
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
150-
type_variable_table_snapshot: Vec<TypeVariableData>,
152+
type_variable_table_snapshot: Vec<TypeVariableFlags>,
151153
}
152154

153155
impl<'a> InferenceTable<'a> {
@@ -169,27 +171,27 @@ impl<'a> InferenceTable<'a> {
169171
/// result.
170172
pub(super) fn propagate_diverging_flag(&mut self) {
171173
for i in 0..self.type_variable_table.len() {
172-
if !self.type_variable_table[i].diverging {
174+
if !self.type_variable_table[i].contains(TypeVariableFlags::DIVERGING) {
173175
continue;
174176
}
175177
let v = InferenceVar::from(i as u32);
176178
let root = self.var_unification_table.inference_var_root(v);
177179
if let Some(data) = self.type_variable_table.get_mut(root.index() as usize) {
178-
data.diverging = true;
180+
*data |= TypeVariableFlags::DIVERGING;
179181
}
180182
}
181183
}
182184

183185
pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
184-
self.type_variable_table[iv.index() as usize].diverging = diverging;
186+
self.type_variable_table[iv.index() as usize].set(TypeVariableFlags::DIVERGING, diverging);
185187
}
186188

187189
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
188190
match kind {
189191
_ if self
190192
.type_variable_table
191193
.get(iv.index() as usize)
192-
.map_or(false, |data| data.diverging) =>
194+
.map_or(false, |data| data.contains(TypeVariableFlags::DIVERGING)) =>
193195
{
194196
TyKind::Never
195197
}
@@ -247,18 +249,18 @@ impl<'a> InferenceTable<'a> {
247249
}
248250

249251
fn extend_type_variable_table(&mut self, to_index: usize) {
250-
self.type_variable_table.extend(
251-
(0..1 + to_index - self.type_variable_table.len())
252-
.map(|_| TypeVariableData { diverging: false }),
253-
);
252+
let count = to_index - self.type_variable_table.len() + 1;
253+
self.type_variable_table.extend(iter::repeat(TypeVariableFlags::default()).take(count));
254254
}
255255

256256
fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
257257
let var = self.var_unification_table.new_variable(UniverseIndex::ROOT);
258258
// Chalk might have created some type variables for its own purposes that we don't know about...
259259
self.extend_type_variable_table(var.index() as usize);
260260
assert_eq!(var.index() as usize, self.type_variable_table.len() - 1);
261-
self.type_variable_table[var.index() as usize].diverging = diverging;
261+
if diverging {
262+
self.type_variable_table[var.index() as usize] |= TypeVariableFlags::DIVERGING;
263+
}
262264
var.to_ty_with_kind(Interner, kind)
263265
}
264266

0 commit comments

Comments
 (0)