From 31aaa6a8cadb10a9f707949fc3fc3d557c44a743 Mon Sep 17 00:00:00 2001 From: Mango Date: Wed, 28 Oct 2020 20:24:29 -0500 Subject: [PATCH 1/3] Add TypeFlags for TyKind in chalk-ir --- Cargo.lock | 1 + chalk-integration/src/test_macros.rs | 10 ++ chalk-ir/Cargo.toml | 1 + chalk-ir/src/lib.rs | 193 ++++++++++++++++++++++++++- tests/test/mod.rs | 1 + tests/test/type_flags.rs | 152 +++++++++++++++++++++ 6 files changed, 355 insertions(+), 3 deletions(-) create mode 100644 tests/test/type_flags.rs diff --git a/Cargo.lock b/Cargo.lock index 358e6ca58ca..8b60646fced 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,6 +211,7 @@ dependencies = [ name = "chalk-ir" version = "0.44.0-dev.0" dependencies = [ + "bitflags", "chalk-derive", "lazy_static", ] diff --git a/chalk-integration/src/test_macros.rs b/chalk-integration/src/test_macros.rs index 6febabc7134..7edb93e9207 100644 --- a/chalk-integration/src/test_macros.rs +++ b/chalk-integration/src/test_macros.rs @@ -119,3 +119,13 @@ macro_rules! lifetime { lifetime!($($b)*) }; } + +#[macro_export] +macro_rules! empty_substitution { + () => { + chalk_ir::Substitution::from_iter( + &chalk_integration::interner::ChalkIr, + Vec::>::new(), + ); + }; +} diff --git a/chalk-ir/Cargo.toml b/chalk-ir/Cargo.toml index fd27cfd07e5..f9ec00af424 100644 --- a/chalk-ir/Cargo.toml +++ b/chalk-ir/Cargo.toml @@ -11,4 +11,5 @@ edition = "2018" [dependencies] lazy_static = "1.4.0" +bitflags = "1.2.1" chalk-derive = { version = "0.44.0-dev.0", path = "../chalk-derive" } diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 59d8335a6fe..0d64c32d565 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -14,7 +14,8 @@ use chalk_derive::{Fold, HasInterner, SuperVisit, Visit, Zip}; use std::marker::PhantomData; pub use crate::debug::SeparatorTraitRef; - +#[macro_use(bitflags)] +extern crate bitflags; /// Uninhabited (empty) type, used in combination with `PhantomData`. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Void {} @@ -411,11 +412,148 @@ pub struct Ty { interned: I::InternedType, } +///compute type flags for Lifetime +fn compute_lifetime_flags(lifetime: &Lifetime, interner: &I) -> TypeFlags { + match lifetime.data(&interner) { + LifetimeData::InferenceVar(_) => { + TypeFlags::HAS_RE_INFER + | TypeFlags::HAS_FREE_LOCAL_REGIONS + | TypeFlags::HAS_FREE_REGIONS + } + LifetimeData::Placeholder(_) => { + TypeFlags::HAS_RE_PLACEHOLDER + | TypeFlags::HAS_FREE_LOCAL_REGIONS + | TypeFlags::HAS_FREE_REGIONS + } + LifetimeData::Static | LifetimeData::Phantom(_, _) | LifetimeData::BoundVar(_) => { + TypeFlags::empty() + } + } +} + +/// Compute type flags for Substitution +fn compute_substitution_flags( + substitution: &Substitution, + interner: &I, +) -> TypeFlags { + let mut flags = TypeFlags::empty(); + for generic_arg in substitution.iter(&interner) { + flags |= compute_generic_arg_flags(generic_arg, &interner); + } + flags +} + +/// Compute type flags for GenericArg +fn compute_generic_arg_flags(generic_arg: &GenericArg, interner: &I) -> TypeFlags { + match generic_arg.data(&interner) { + GenericArgData::Ty(ty) => ty.data(interner).flags, + GenericArgData::Lifetime(lifetime) => compute_lifetime_flags(lifetime, interner), + GenericArgData::Const(constant) => { + let data = constant.data(&interner); + let flags = data.ty.data(interner).flags; + match data.value { + ConstValue::BoundVar(_) => flags, + ConstValue::InferenceVar(_) => { + flags | TypeFlags::HAS_CT_INFER | TypeFlags::STILL_FURTHER_SPECIALIZABLE + } + ConstValue::Placeholder(_) => { + flags | TypeFlags::HAS_CT_PLACEHOLDER | TypeFlags::STILL_FURTHER_SPECIALIZABLE + } + ConstValue::Concrete(_) => flags, + } + } + } +} + +/// Compute type flags for aliases +fn compute_alias_flags(alias_ty: &AliasTy, interner: &I) -> TypeFlags { + match alias_ty { + AliasTy::Projection(projection_ty) => { + TypeFlags::HAS_TY_PROJECTION + | compute_substitution_flags(&(projection_ty.substitution), interner) + } + AliasTy::Opaque(opaque_ty) => { + TypeFlags::HAS_TY_OPAQUE + | compute_substitution_flags(&(opaque_ty.substitution), interner) + } + } +} + +/// Compute type flags for a TyKind +fn compute_flags(kind: &TyKind, interner: &I) -> TypeFlags { + match kind { + TyKind::Adt(_, substitution) + | TyKind::AssociatedType(_, substitution) + | TyKind::Tuple(_, substitution) + | TyKind::Closure(_, substitution) + | TyKind::Generator(_, substitution) + | TyKind::GeneratorWitness(_, substitution) + | TyKind::FnDef(_, substitution) => compute_substitution_flags(substitution, interner), + TyKind::Scalar(_) | TyKind::Str | TyKind::Never | TyKind::Foreign(_) => TypeFlags::empty(), + TyKind::OpaqueType(_, substitution) => { + TypeFlags::HAS_TY_OPAQUE | compute_substitution_flags(substitution, interner) + } + TyKind::Error => TypeFlags::HAS_ERROR, + TyKind::Slice(ty) | TyKind::Raw(_, ty) => ty.data(interner).flags, + TyKind::Ref(_, lifetime, ty) => { + compute_lifetime_flags(lifetime, interner) | ty.data(interner).flags + } + TyKind::Array(ty, const_ty) => { + let flags = ty.data(interner).flags; + let const_data = const_ty.data(interner); + flags + | const_data.ty.data(interner).flags + | match const_data.value { + ConstValue::BoundVar(_) | ConstValue::Concrete(_) => TypeFlags::empty(), + ConstValue::InferenceVar(_) => { + TypeFlags::HAS_CT_INFER | TypeFlags::STILL_FURTHER_SPECIALIZABLE + } + ConstValue::Placeholder(_) => { + TypeFlags::HAS_CT_PLACEHOLDER | TypeFlags::STILL_FURTHER_SPECIALIZABLE + } + } + } + TyKind::Placeholder(_) => TypeFlags::HAS_TY_PLACEHOLDER, + TyKind::Dyn(dyn_ty) => { + let lifetime_flags = compute_lifetime_flags(&(dyn_ty.lifetime), &interner); + let mut dyn_flags = TypeFlags::empty(); + for var_kind in dyn_ty.bounds.value.iter(&interner) { + match &(var_kind.value) { + WhereClause::Implemented(trait_ref) => { + dyn_flags |= compute_substitution_flags(&(trait_ref.substitution), interner) + } + WhereClause::AliasEq(alias_eq) => { + dyn_flags |= compute_alias_flags(&(alias_eq.alias), &interner); + dyn_flags |= alias_eq.ty.data(&interner).flags; + } + WhereClause::LifetimeOutlives(lifetime_outlives) => { + dyn_flags |= compute_lifetime_flags(&(lifetime_outlives.a), &interner) + | compute_lifetime_flags(&(lifetime_outlives.b), &interner); + } + WhereClause::TypeOutlives(type_outlives) => { + dyn_flags |= type_outlives.ty.data(&interner).flags; + dyn_flags |= compute_lifetime_flags(&(type_outlives.lifetime), &interner); + } + } + } + lifetime_flags | dyn_flags + } + TyKind::Alias(alias_ty) => compute_alias_flags(&alias_ty, &interner), + TyKind::BoundVar(_) => TypeFlags::empty(), + TyKind::InferenceVar(_, _) => TypeFlags::HAS_TY_INFER, + TyKind::Function(fn_pointer) => { + compute_substitution_flags(&(fn_pointer.substitution), interner) + } + } +} + impl Ty { /// Creates a type from `TyKind`. pub fn new(interner: &I, data: impl CastTo>) -> Self { + let ty_kind = data.cast(&interner); let data = TyData { - kind: data.cast(interner), + flags: compute_flags(&ty_kind, &interner), + kind: ty_kind, }; Ty { interned: I::intern_ty(interner, data), @@ -530,8 +668,57 @@ impl Ty { pub struct TyData { /// The kind pub kind: TyKind, + /// Type flags + pub flags: TypeFlags, +} + +bitflags! { + /// Contains flags indicating various properties of a Ty + pub struct TypeFlags : u16 { + /// Does the type contain an InferenceVar + const HAS_TY_INFER = 1; + /// Does the type contain a lifetime with an InferenceVar + const HAS_RE_INFER = 1 << 1; + /// Does the type contain a ConstValue with an InferenceVar + const HAS_CT_INFER = 1 << 2; + /// Does the type contain a Placeholder TyKind + const HAS_TY_PLACEHOLDER = 1 << 3; + /// Does the type contain a lifetime with a Placeholder + const HAS_RE_PLACEHOLDER = 1 << 4; + /// Does the type contain a ConstValue Placeholder + const HAS_CT_PLACEHOLDER = 1 << 5; + /// True when the type has free lifetimes related to a local context + const HAS_FREE_LOCAL_REGIONS = 1 << 6; + /// Does the type contain a projection of an associated type + const HAS_TY_PROJECTION = 1 << 7; + /// Does the type contain an opaque type + const HAS_TY_OPAQUE = 1 << 8; + /// Does the type contain an unevaluated const projection + const HAS_CT_PROJECTION = 1 << 9; + /// Does the type contain an error + const HAS_ERROR = 1 << 10; + /// Does the type contain any free lifetimes + const HAS_FREE_REGIONS = 1 << 11; + /// True when the type contains lifetimes that will be substituted when function is called + const HAS_RE_LATE_BOUND = 1 << 12; + /// True when the type contains an erased lifetime + const HAS_RE_ERASED = 1 << 13; + /// Does the type contain placeholders or inference variables that could be replaced later + const STILL_FURTHER_SPECIALIZABLE = 1 << 14; + + /// True when the type contains free names local to a particular context + const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_INFER.bits + | TypeFlags::HAS_CT_INFER.bits + | TypeFlags::HAS_TY_PLACEHOLDER.bits + | TypeFlags::HAS_CT_PLACEHOLDER.bits + | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits; + + /// Does the type contain any form of projection + const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits + | TypeFlags::HAS_TY_OPAQUE.bits + | TypeFlags::HAS_CT_PROJECTION.bits; + } } - /// Type data, which holds the actual type information. #[derive(Clone, PartialEq, Eq, Hash, HasInterner)] pub enum TyKind { diff --git a/tests/test/mod.rs b/tests/test/mod.rs index f8d39aaabec..0b97bfe1b45 100644 --- a/tests/test/mod.rs +++ b/tests/test/mod.rs @@ -348,6 +348,7 @@ mod slices; mod string; mod subtype; mod tuples; +mod type_flags; mod unify; mod unpin; mod unsize; diff --git a/tests/test/type_flags.rs b/tests/test/type_flags.rs new file mode 100644 index 00000000000..a943376e98a --- /dev/null +++ b/tests/test/type_flags.rs @@ -0,0 +1,152 @@ +use chalk_integration::{empty_substitution, lifetime, ty}; +use chalk_ir::{PlaceholderIndex, Ty, TyKind, UniverseIndex}; + +#[test] +fn placeholder_ty_flags_correct() { + let placeholder_ty = ty!(placeholder 0); + assert_eq!( + placeholder_ty + .data(&chalk_integration::interner::ChalkIr) + .flags, + chalk_ir::TypeFlags::HAS_TY_PLACEHOLDER + ); +} + +#[test] +fn opaque_ty_flags_correct() { + let x: Vec> = + vec![chalk_ir::GenericArg::new( + &chalk_integration::interner::ChalkIr, + chalk_ir::GenericArgData::Const(chalk_ir::Const::new( + &chalk_integration::interner::ChalkIr, + chalk_ir::ConstData { + ty: Ty::new( + &chalk_integration::interner::ChalkIr, + TyKind::Placeholder(PlaceholderIndex { + ui: chalk_ir::UniverseIndex::ROOT, + idx: 0, + }), + ), + value: chalk_ir::ConstValue::InferenceVar(chalk_ir::InferenceVar::from(0)), + }, + )), + )]; + let opaque_ty_kind = TyKind::OpaqueType( + chalk_ir::OpaqueTyId { + 0: chalk_integration::interner::RawId { index: 0 }, + }, + chalk_ir::Substitution::from_iter(&chalk_integration::interner::ChalkIr, x), + ); + let opaque_ty = Ty::new(&chalk_integration::interner::ChalkIr, opaque_ty_kind); + assert_eq!( + opaque_ty.data(&chalk_integration::interner::ChalkIr).flags, + chalk_ir::TypeFlags::HAS_TY_OPAQUE + | chalk_ir::TypeFlags::HAS_CT_INFER + | chalk_ir::TypeFlags::STILL_FURTHER_SPECIALIZABLE + | chalk_ir::TypeFlags::HAS_TY_PLACEHOLDER + ); +} + +#[test] +fn dyn_ty_flags_correct() { + let internal_ty = Ty::new( + &chalk_integration::interner::ChalkIr, + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool), + ); + let projection_ty = chalk_ir::ProjectionTy { + associated_ty_id: chalk_ir::AssocTypeId { + 0: chalk_integration::interner::RawId { index: 0 }, + }, + substitution: empty_substitution!(), + }; + let bounds = chalk_ir::Binders::< + chalk_ir::QuantifiedWhereClauses, + >::empty( + &chalk_integration::interner::ChalkIr, + chalk_ir::QuantifiedWhereClauses::from_iter( + &chalk_integration::interner::ChalkIr, + vec![chalk_ir::Binders::< + chalk_ir::WhereClause, + >::empty( + &chalk_integration::interner::ChalkIr, + chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { + ty: internal_ty, + alias: chalk_ir::AliasTy::Projection(projection_ty), + }), + )], + ), + ); + let dyn_ty = chalk_ir::DynTy { + lifetime: lifetime!(placeholder 5), + bounds: bounds, + }; + let ty = chalk_ir::Ty::new(&chalk_integration::interner::ChalkIr, TyKind::Dyn(dyn_ty)); + assert_eq!( + ty.data(&chalk_integration::interner::ChalkIr).flags, + chalk_ir::TypeFlags::HAS_TY_PROJECTION + | chalk_ir::TypeFlags::HAS_RE_PLACEHOLDER + | chalk_ir::TypeFlags::HAS_FREE_LOCAL_REGIONS + | chalk_ir::TypeFlags::HAS_FREE_REGIONS + ); +} + +#[test] +fn flagless_ty_has_no_flags() { + let ty = Ty::new(&chalk_integration::interner::ChalkIr, TyKind::Str); + assert_eq!( + ty.data(&chalk_integration::interner::ChalkIr).flags, + chalk_ir::TypeFlags::empty() + ); + + let fn_ty = Ty::new( + &chalk_integration::interner::ChalkIr, + TyKind::Function(chalk_ir::FnPointer { + num_binders: 0, + substitution: empty_substitution!(), + sig: chalk_ir::FnSig { + abi: chalk_integration::interner::ChalkFnAbi::Rust, + safety: chalk_ir::Safety::Safe, + variadic: false, + }, + }), + ); + assert_eq!( + fn_ty.data(&chalk_integration::interner::ChalkIr).flags, + chalk_ir::TypeFlags::empty() + ); +} + +#[test] +fn flagless_lifetime_contributes_no_flags() { + let substitutions = chalk_ir::Substitution::from_iter( + &chalk_integration::interner::ChalkIr, + vec![ + chalk_ir::GenericArg::new( + &chalk_integration::interner::ChalkIr, + chalk_ir::GenericArgData::Lifetime(chalk_ir::Lifetime::new( + &chalk_integration::interner::ChalkIr, + chalk_ir::LifetimeData::Static, + )), + ), + chalk_ir::GenericArg::new( + &chalk_integration::interner::ChalkIr, + chalk_ir::GenericArgData::Lifetime(lifetime!(bound 5)), + ), + ], + ); + + let ty = Ty::new( + &chalk_integration::interner::ChalkIr, + TyKind::Adt( + chalk_ir::AdtId { + 0: chalk_integration::interner::RawId { index: 0 }, + }, + substitutions, + ), + ); + + assert_eq!( + ty.data(&chalk_integration::interner::ChalkIr).flags, + chalk_ir::TypeFlags::empty() + ); +} From 2ca1334a99b8b2964939348fe14d4c9577668999 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 9 Dec 2020 04:31:40 -0500 Subject: [PATCH 2/3] Cleanup and review comments --- chalk-integration/src/test_macros.rs | 5 +- chalk-ir/src/lib.rs | 18 +-- tests/test/type_flags.rs | 166 +++++++++++---------------- 3 files changed, 80 insertions(+), 109 deletions(-) diff --git a/chalk-integration/src/test_macros.rs b/chalk-integration/src/test_macros.rs index 7edb93e9207..8ac6934ec33 100644 --- a/chalk-integration/src/test_macros.rs +++ b/chalk-integration/src/test_macros.rs @@ -123,9 +123,6 @@ macro_rules! lifetime { #[macro_export] macro_rules! empty_substitution { () => { - chalk_ir::Substitution::from_iter( - &chalk_integration::interner::ChalkIr, - Vec::>::new(), - ); + chalk_ir::Substitution::empty(&chalk_integration::interner::ChalkIr) }; } diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 0d64c32d565..b8797fe5c52 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -425,9 +425,10 @@ fn compute_lifetime_flags(lifetime: &Lifetime, interner: &I) -> | TypeFlags::HAS_FREE_LOCAL_REGIONS | TypeFlags::HAS_FREE_REGIONS } - LifetimeData::Static | LifetimeData::Phantom(_, _) | LifetimeData::BoundVar(_) => { - TypeFlags::empty() - } + LifetimeData::Static | LifetimeData::Empty(_) => TypeFlags::HAS_FREE_REGIONS, + LifetimeData::Phantom(_, _) => TypeFlags::empty(), + LifetimeData::BoundVar(_) => TypeFlags::HAS_RE_LATE_BOUND, + LifetimeData::Erased => TypeFlags::HAS_RE_ERASED, } } @@ -489,10 +490,11 @@ fn compute_flags(kind: &TyKind, interner: &I) -> TypeFlags { | TyKind::Generator(_, substitution) | TyKind::GeneratorWitness(_, substitution) | TyKind::FnDef(_, substitution) => compute_substitution_flags(substitution, interner), - TyKind::Scalar(_) | TyKind::Str | TyKind::Never | TyKind::Foreign(_) => TypeFlags::empty(), - TyKind::OpaqueType(_, substitution) => { - TypeFlags::HAS_TY_OPAQUE | compute_substitution_flags(substitution, interner) - } + TyKind::Scalar(_) + | TyKind::Str + | TyKind::Never + | TyKind::Foreign(_) + | TyKind::OpaqueType(_, _) => TypeFlags::empty(), TyKind::Error => TypeFlags::HAS_ERROR, TyKind::Slice(ty) | TyKind::Raw(_, ty) => ty.data(interner).flags, TyKind::Ref(_, lifetime, ty) => { @@ -542,7 +544,7 @@ fn compute_flags(kind: &TyKind, interner: &I) -> TypeFlags { TyKind::BoundVar(_) => TypeFlags::empty(), TyKind::InferenceVar(_, _) => TypeFlags::HAS_TY_INFER, TyKind::Function(fn_pointer) => { - compute_substitution_flags(&(fn_pointer.substitution), interner) + compute_substitution_flags(&fn_pointer.substitution.0, interner) } } } diff --git a/tests/test/type_flags.rs b/tests/test/type_flags.rs index a943376e98a..c568fc7306f 100644 --- a/tests/test/type_flags.rs +++ b/tests/test/type_flags.rs @@ -1,74 +1,64 @@ +use chalk_integration::interner::ChalkIr; use chalk_integration::{empty_substitution, lifetime, ty}; -use chalk_ir::{PlaceholderIndex, Ty, TyKind, UniverseIndex}; +use chalk_ir::cast::Cast; +use chalk_ir::{PlaceholderIndex, TyKind, TypeFlags, UniverseIndex}; #[test] fn placeholder_ty_flags_correct() { let placeholder_ty = ty!(placeholder 0); assert_eq!( - placeholder_ty - .data(&chalk_integration::interner::ChalkIr) - .flags, - chalk_ir::TypeFlags::HAS_TY_PLACEHOLDER + placeholder_ty.data(&ChalkIr).flags, + TypeFlags::HAS_TY_PLACEHOLDER ); } #[test] fn opaque_ty_flags_correct() { - let x: Vec> = - vec![chalk_ir::GenericArg::new( - &chalk_integration::interner::ChalkIr, - chalk_ir::GenericArgData::Const(chalk_ir::Const::new( - &chalk_integration::interner::ChalkIr, - chalk_ir::ConstData { - ty: Ty::new( - &chalk_integration::interner::ChalkIr, - TyKind::Placeholder(PlaceholderIndex { - ui: chalk_ir::UniverseIndex::ROOT, - idx: 0, - }), - ), - value: chalk_ir::ConstValue::InferenceVar(chalk_ir::InferenceVar::from(0)), - }, - )), - )]; - let opaque_ty_kind = TyKind::OpaqueType( - chalk_ir::OpaqueTyId { + let opaque_ty = TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { + opaque_ty_id: chalk_ir::OpaqueTyId { 0: chalk_integration::interner::RawId { index: 0 }, }, - chalk_ir::Substitution::from_iter(&chalk_integration::interner::ChalkIr, x), - ); - let opaque_ty = Ty::new(&chalk_integration::interner::ChalkIr, opaque_ty_kind); + substitution: chalk_ir::Substitution::from_iter( + &ChalkIr, + Some( + chalk_ir::ConstData { + ty: TyKind::Placeholder(PlaceholderIndex { + ui: chalk_ir::UniverseIndex::ROOT, + idx: 0, + }) + .intern(&ChalkIr), + value: chalk_ir::ConstValue::InferenceVar(chalk_ir::InferenceVar::from(0)), + } + .intern(&ChalkIr) + .cast(&ChalkIr), + ), + ), + })) + .intern(&ChalkIr); assert_eq!( - opaque_ty.data(&chalk_integration::interner::ChalkIr).flags, - chalk_ir::TypeFlags::HAS_TY_OPAQUE - | chalk_ir::TypeFlags::HAS_CT_INFER - | chalk_ir::TypeFlags::STILL_FURTHER_SPECIALIZABLE - | chalk_ir::TypeFlags::HAS_TY_PLACEHOLDER + opaque_ty.data(&ChalkIr).flags, + TypeFlags::HAS_TY_OPAQUE + | TypeFlags::HAS_CT_INFER + | TypeFlags::STILL_FURTHER_SPECIALIZABLE + | TypeFlags::HAS_TY_PLACEHOLDER ); } #[test] fn dyn_ty_flags_correct() { - let internal_ty = Ty::new( - &chalk_integration::interner::ChalkIr, - chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool), - ); + let internal_ty = TyKind::Scalar(chalk_ir::Scalar::Bool).intern(&ChalkIr); let projection_ty = chalk_ir::ProjectionTy { associated_ty_id: chalk_ir::AssocTypeId { 0: chalk_integration::interner::RawId { index: 0 }, }, substitution: empty_substitution!(), }; - let bounds = chalk_ir::Binders::< - chalk_ir::QuantifiedWhereClauses, - >::empty( - &chalk_integration::interner::ChalkIr, + let bounds = chalk_ir::Binders::>::empty( + &ChalkIr, chalk_ir::QuantifiedWhereClauses::from_iter( - &chalk_integration::interner::ChalkIr, - vec![chalk_ir::Binders::< - chalk_ir::WhereClause, - >::empty( - &chalk_integration::interner::ChalkIr, + &ChalkIr, + vec![chalk_ir::Binders::>::empty( + &ChalkIr, chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { ty: internal_ty, alias: chalk_ir::AliasTy::Projection(projection_ty), @@ -78,75 +68,57 @@ fn dyn_ty_flags_correct() { ); let dyn_ty = chalk_ir::DynTy { lifetime: lifetime!(placeholder 5), - bounds: bounds, + bounds, }; - let ty = chalk_ir::Ty::new(&chalk_integration::interner::ChalkIr, TyKind::Dyn(dyn_ty)); + let ty = TyKind::Dyn(dyn_ty).intern(&ChalkIr); assert_eq!( - ty.data(&chalk_integration::interner::ChalkIr).flags, - chalk_ir::TypeFlags::HAS_TY_PROJECTION - | chalk_ir::TypeFlags::HAS_RE_PLACEHOLDER - | chalk_ir::TypeFlags::HAS_FREE_LOCAL_REGIONS - | chalk_ir::TypeFlags::HAS_FREE_REGIONS + ty.data(&ChalkIr).flags, + TypeFlags::HAS_TY_PROJECTION + | TypeFlags::HAS_RE_PLACEHOLDER + | TypeFlags::HAS_FREE_LOCAL_REGIONS + | TypeFlags::HAS_FREE_REGIONS ); } #[test] fn flagless_ty_has_no_flags() { - let ty = Ty::new(&chalk_integration::interner::ChalkIr, TyKind::Str); - assert_eq!( - ty.data(&chalk_integration::interner::ChalkIr).flags, - chalk_ir::TypeFlags::empty() - ); + let ty = TyKind::Str.intern(&ChalkIr); + assert_eq!(ty.data(&ChalkIr).flags, TypeFlags::empty()); - let fn_ty = Ty::new( - &chalk_integration::interner::ChalkIr, - TyKind::Function(chalk_ir::FnPointer { - num_binders: 0, - substitution: empty_substitution!(), - sig: chalk_ir::FnSig { - abi: chalk_integration::interner::ChalkFnAbi::Rust, - safety: chalk_ir::Safety::Safe, - variadic: false, - }, - }), - ); - assert_eq!( - fn_ty.data(&chalk_integration::interner::ChalkIr).flags, - chalk_ir::TypeFlags::empty() - ); + let fn_ty = TyKind::Function(chalk_ir::FnPointer { + num_binders: 0, + substitution: chalk_ir::FnSubst(empty_substitution!()), + sig: chalk_ir::FnSig { + abi: chalk_integration::interner::ChalkFnAbi::Rust, + safety: chalk_ir::Safety::Safe, + variadic: false, + }, + }) + .intern(&ChalkIr); + assert_eq!(fn_ty.data(&ChalkIr).flags, TypeFlags::empty()); } #[test] -fn flagless_lifetime_contributes_no_flags() { +fn static_and_bound_lifetimes() { let substitutions = chalk_ir::Substitution::from_iter( - &chalk_integration::interner::ChalkIr, + &ChalkIr, vec![ - chalk_ir::GenericArg::new( - &chalk_integration::interner::ChalkIr, - chalk_ir::GenericArgData::Lifetime(chalk_ir::Lifetime::new( - &chalk_integration::interner::ChalkIr, - chalk_ir::LifetimeData::Static, - )), - ), - chalk_ir::GenericArg::new( - &chalk_integration::interner::ChalkIr, - chalk_ir::GenericArgData::Lifetime(lifetime!(bound 5)), - ), + chalk_ir::GenericArgData::Lifetime(chalk_ir::LifetimeData::Static.intern(&ChalkIr)) + .intern(&ChalkIr), + chalk_ir::GenericArgData::Lifetime(lifetime!(bound 5)).intern(&ChalkIr), ], ); - let ty = Ty::new( - &chalk_integration::interner::ChalkIr, - TyKind::Adt( - chalk_ir::AdtId { - 0: chalk_integration::interner::RawId { index: 0 }, - }, - substitutions, - ), - ); + let ty = TyKind::Adt( + chalk_ir::AdtId { + 0: chalk_integration::interner::RawId { index: 0 }, + }, + substitutions, + ) + .intern(&ChalkIr); assert_eq!( - ty.data(&chalk_integration::interner::ChalkIr).flags, - chalk_ir::TypeFlags::empty() + ty.data(&ChalkIr).flags, + TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_LATE_BOUND ); } From a8b61ffb35077bdcaadba0d9218b027419cb0ed3 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 11 Dec 2020 16:30:45 -0500 Subject: [PATCH 3/3] Comput flags for substs of OpaqueType --- chalk-ir/src/lib.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index b8797fe5c52..c83f13e17bd 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -489,12 +489,9 @@ fn compute_flags(kind: &TyKind, interner: &I) -> TypeFlags { | TyKind::Closure(_, substitution) | TyKind::Generator(_, substitution) | TyKind::GeneratorWitness(_, substitution) - | TyKind::FnDef(_, substitution) => compute_substitution_flags(substitution, interner), - TyKind::Scalar(_) - | TyKind::Str - | TyKind::Never - | TyKind::Foreign(_) - | TyKind::OpaqueType(_, _) => TypeFlags::empty(), + | TyKind::FnDef(_, substitution) + | TyKind::OpaqueType(_, substitution) => compute_substitution_flags(substitution, interner), + TyKind::Scalar(_) | TyKind::Str | TyKind::Never | TyKind::Foreign(_) => TypeFlags::empty(), TyKind::Error => TypeFlags::HAS_ERROR, TyKind::Slice(ty) | TyKind::Raw(_, ty) => ty.data(interner).flags, TyKind::Ref(_, lifetime, ty) => {