mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Store diverging flag for type variables as bitflags
This commit is contained in:
parent
a97c71f92d
commit
1bfc732b78
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -557,6 +557,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"base-db",
|
"base-db",
|
||||||
|
"bitflags",
|
||||||
"chalk-derive",
|
"chalk-derive",
|
||||||
"chalk-ir",
|
"chalk-ir",
|
||||||
"chalk-recursive",
|
"chalk-recursive",
|
||||||
|
@ -13,6 +13,7 @@ doctest = false
|
|||||||
cov-mark = "2.0.0-pre.1"
|
cov-mark = "2.0.0-pre.1"
|
||||||
itertools = "0.10.5"
|
itertools = "0.10.5"
|
||||||
arrayvec = "0.7.2"
|
arrayvec = "0.7.2"
|
||||||
|
bitflags = "1.3.2"
|
||||||
smallvec = "1.10.0"
|
smallvec = "1.10.0"
|
||||||
ena = "0.14.0"
|
ena = "0.14.0"
|
||||||
tracing = "0.1.35"
|
tracing = "0.1.35"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Unification and canonicalization logic.
|
//! Unification and canonicalization logic.
|
||||||
|
|
||||||
use std::{fmt, mem, sync::Arc};
|
use std::{fmt, iter, mem, sync::Arc};
|
||||||
|
|
||||||
use chalk_ir::{
|
use chalk_ir::{
|
||||||
cast::Cast, fold::TypeFoldable, interner::HasInterner, zip::Zip, CanonicalVarKind, FloatTy,
|
cast::Cast, fold::TypeFoldable, interner::HasInterner, zip::Zip, CanonicalVarKind, FloatTy,
|
||||||
@ -128,9 +128,11 @@ pub(crate) fn unify(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
bitflags::bitflags! {
|
||||||
pub(crate) struct TypeVariableData {
|
#[derive(Default)]
|
||||||
diverging: bool,
|
pub(crate) struct TypeVariableFlags: u8 {
|
||||||
|
const DIVERGING = 1 << 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChalkInferenceTable = chalk_solve::infer::InferenceTable<Interner>;
|
type ChalkInferenceTable = chalk_solve::infer::InferenceTable<Interner>;
|
||||||
@ -140,14 +142,14 @@ pub(crate) struct InferenceTable<'a> {
|
|||||||
pub(crate) db: &'a dyn HirDatabase,
|
pub(crate) db: &'a dyn HirDatabase,
|
||||||
pub(crate) trait_env: Arc<TraitEnvironment>,
|
pub(crate) trait_env: Arc<TraitEnvironment>,
|
||||||
var_unification_table: ChalkInferenceTable,
|
var_unification_table: ChalkInferenceTable,
|
||||||
type_variable_table: Vec<TypeVariableData>,
|
type_variable_table: Vec<TypeVariableFlags>,
|
||||||
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
|
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct InferenceTableSnapshot {
|
pub(crate) struct InferenceTableSnapshot {
|
||||||
var_table_snapshot: chalk_solve::infer::InferenceSnapshot<Interner>,
|
var_table_snapshot: chalk_solve::infer::InferenceSnapshot<Interner>,
|
||||||
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
|
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
|
||||||
type_variable_table_snapshot: Vec<TypeVariableData>,
|
type_variable_table_snapshot: Vec<TypeVariableFlags>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> InferenceTable<'a> {
|
impl<'a> InferenceTable<'a> {
|
||||||
@ -169,19 +171,19 @@ impl<'a> InferenceTable<'a> {
|
|||||||
/// result.
|
/// result.
|
||||||
pub(super) fn propagate_diverging_flag(&mut self) {
|
pub(super) fn propagate_diverging_flag(&mut self) {
|
||||||
for i in 0..self.type_variable_table.len() {
|
for i in 0..self.type_variable_table.len() {
|
||||||
if !self.type_variable_table[i].diverging {
|
if !self.type_variable_table[i].contains(TypeVariableFlags::DIVERGING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let v = InferenceVar::from(i as u32);
|
let v = InferenceVar::from(i as u32);
|
||||||
let root = self.var_unification_table.inference_var_root(v);
|
let root = self.var_unification_table.inference_var_root(v);
|
||||||
if let Some(data) = self.type_variable_table.get_mut(root.index() as usize) {
|
if let Some(data) = self.type_variable_table.get_mut(root.index() as usize) {
|
||||||
data.diverging = true;
|
*data |= TypeVariableFlags::DIVERGING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
|
pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
|
||||||
self.type_variable_table[iv.index() as usize].diverging = diverging;
|
self.type_variable_table[iv.index() as usize].set(TypeVariableFlags::DIVERGING, diverging);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
|
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
|
||||||
@ -189,7 +191,7 @@ impl<'a> InferenceTable<'a> {
|
|||||||
_ if self
|
_ if self
|
||||||
.type_variable_table
|
.type_variable_table
|
||||||
.get(iv.index() as usize)
|
.get(iv.index() as usize)
|
||||||
.map_or(false, |data| data.diverging) =>
|
.map_or(false, |data| data.contains(TypeVariableFlags::DIVERGING)) =>
|
||||||
{
|
{
|
||||||
TyKind::Never
|
TyKind::Never
|
||||||
}
|
}
|
||||||
@ -247,10 +249,8 @@ impl<'a> InferenceTable<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn extend_type_variable_table(&mut self, to_index: usize) {
|
fn extend_type_variable_table(&mut self, to_index: usize) {
|
||||||
self.type_variable_table.extend(
|
let count = to_index - self.type_variable_table.len() + 1;
|
||||||
(0..1 + to_index - self.type_variable_table.len())
|
self.type_variable_table.extend(iter::repeat(TypeVariableFlags::default()).take(count));
|
||||||
.map(|_| TypeVariableData { diverging: false }),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
|
fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
|
||||||
@ -258,7 +258,9 @@ impl<'a> InferenceTable<'a> {
|
|||||||
// Chalk might have created some type variables for its own purposes that we don't know about...
|
// Chalk might have created some type variables for its own purposes that we don't know about...
|
||||||
self.extend_type_variable_table(var.index() as usize);
|
self.extend_type_variable_table(var.index() as usize);
|
||||||
assert_eq!(var.index() as usize, self.type_variable_table.len() - 1);
|
assert_eq!(var.index() as usize, self.type_variable_table.len() - 1);
|
||||||
self.type_variable_table[var.index() as usize].diverging = diverging;
|
if diverging {
|
||||||
|
self.type_variable_table[var.index() as usize] |= TypeVariableFlags::DIVERGING;
|
||||||
|
}
|
||||||
var.to_ty_with_kind(Interner, kind)
|
var.to_ty_with_kind(Interner, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user