Skip to content

Commit

Permalink
Make ty_data return TyData and add ty_kind
Browse files Browse the repository at this point in the history
  • Loading branch information
jackh726 committed Oct 20, 2020
1 parent e4b9f46 commit 5452311
Show file tree
Hide file tree
Showing 26 changed files with 100 additions and 70 deletions.
4 changes: 2 additions & 2 deletions book/src/types/role_of_interner.md
Expand Up @@ -52,8 +52,8 @@ type [`InternedTy`] and two related methods, [`intern_ty`] and [`ty_data`]:
trait Interner {
type InternedTy;
fn intern_ty(&self, data: &TyKind<Self>) -> Self::InternedTy;
fn ty_data(data: &Self::InternedTy) -> &TyKind<Self>;
fn intern_ty(&self, data: &TyData<Self>) -> Self::InternedTy;
fn ty_data(data: &Self::InternedTy) -> &TyData<Self>;
}
```

Expand Down
2 changes: 1 addition & 1 deletion chalk-engine/src/slg.rs
Expand Up @@ -371,7 +371,7 @@ impl<I: Interner> MayInvalidate<'_, I> {
/// Returns true if the two types could be unequal.
fn aggregate_tys(&mut self, new: &Ty<I>, current: &Ty<I>) -> bool {
let interner = self.interner;
match (new.data(interner), current.data(interner)) {
match (new.kind(interner), current.kind(interner)) {
(_, TyKind::BoundVar(_)) => {
// If the aggregate solution already has an inference
// variable here, then no matter what type we produce,
Expand Down
2 changes: 1 addition & 1 deletion chalk-engine/src/slg/aggregate.rs
Expand Up @@ -231,7 +231,7 @@ struct AntiUnifier<'infer, 'intern, I: Interner> {
impl<I: Interner> AntiUnifier<'_, '_, I> {
fn aggregate_tys(&mut self, ty0: &Ty<I>, ty1: &Ty<I>) -> Ty<I> {
let interner = self.interner;
match (ty0.data(interner), ty1.data(interner)) {
match (ty0.kind(interner), ty1.kind(interner)) {
// If we see bound things on either side, just drop in a
// fresh variable. This means we will sometimes
// overgeneralize. So for example if we have two
Expand Down
4 changes: 2 additions & 2 deletions chalk-engine/src/slg/resolvent.rs
Expand Up @@ -373,7 +373,7 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {
// "inputs" to the subgoal table. We need to extract the
// resulting answer that the subgoal found and unify it with
// the value from our "pending subgoal".
if let TyKind::BoundVar(answer_depth) = answer.data(interner) {
if let TyKind::BoundVar(answer_depth) = answer.kind(interner) {
if self.unify_free_answer_var(
interner,
*answer_depth,
Expand All @@ -385,7 +385,7 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {

// Otherwise, the answer and the selected subgoal ought to be a perfect match for
// one another.
match (answer.data(interner), pending.data(interner)) {
match (answer.kind(interner), pending.kind(interner)) {
(TyKind::BoundVar(answer_depth), TyKind::BoundVar(pending_depth)) => {
self.assert_matching_vars(*answer_depth, *pending_depth)
}
Expand Down
12 changes: 6 additions & 6 deletions chalk-integration/src/interner.rs
Expand Up @@ -4,11 +4,11 @@ use chalk_ir::{
AdtId, AliasTy, ApplicationTy, AssocTypeId, CanonicalVarKind, CanonicalVarKinds, ConstData,
Constraint, FnDefId, Goals, InEnvironment, Lifetime, OpaqueTy, OpaqueTyId,
ProgramClauseImplication, ProgramClauses, ProjectionTy, QuantifiedWhereClauses,
SeparatorTraitRef, Substitution, TraitId, Ty, VariableKind, VariableKinds,
SeparatorTraitRef, Substitution, TraitId, Ty, TyData, VariableKind, VariableKinds,
};
use chalk_ir::{
GenericArg, GenericArgData, Goal, GoalData, LifetimeData, ProgramClause, ProgramClauseData,
QuantifiedWhereClause, TyKind,
QuantifiedWhereClause,
};
use std::fmt;
use std::fmt::Debug;
Expand Down Expand Up @@ -40,7 +40,7 @@ pub enum ChalkFnAbi {
pub struct ChalkIr;

impl Interner for ChalkIr {
type InternedType = Arc<TyKind<ChalkIr>>;
type InternedType = Arc<TyData<ChalkIr>>;
type InternedLifetime = LifetimeData<ChalkIr>;
type InternedConst = Arc<ConstData<ChalkIr>>;
type InternedConcreteConst = u32;
Expand Down Expand Up @@ -212,11 +212,11 @@ impl Interner for ChalkIr {
tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt)))
}

fn intern_ty(&self, ty: TyKind<ChalkIr>) -> Arc<TyKind<ChalkIr>> {
fn intern_ty(&self, ty: TyData<ChalkIr>) -> Arc<TyData<ChalkIr>> {
Arc::new(ty)
}

fn ty_data<'a>(&self, ty: &'a Arc<TyKind<ChalkIr>>) -> &'a TyKind<Self> {
fn ty_data<'a>(&self, ty: &'a Arc<TyData<ChalkIr>>) -> &'a TyData<Self> {
ty
}

Expand All @@ -236,7 +236,7 @@ impl Interner for ChalkIr {
constant
}

fn const_eq(&self, _ty: &Arc<TyKind<ChalkIr>>, c1: &u32, c2: &u32) -> bool {
fn const_eq(&self, _ty: &Arc<TyData<ChalkIr>>, c1: &u32, c2: &u32) -> bool {
c1 == c2
}

Expand Down
17 changes: 12 additions & 5 deletions chalk-integration/src/lowering.rs
Expand Up @@ -120,11 +120,18 @@ impl Lower for VariableKind {
type Lowered = chalk_ir::WithKind<ChalkIr, Ident>;
fn lower(&self) -> Self::Lowered {
let (kind, n) = match self {
VariableKind::Ty(n) => (chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), n),
VariableKind::IntegerTy(n) => {
(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Integer), n)
}
VariableKind::FloatTy(n) => (chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Float), n),
VariableKind::Ty(n) => (
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
n,
),
VariableKind::IntegerTy(n) => (
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Integer),
n,
),
VariableKind::FloatTy(n) => (
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Float),
n,
),
VariableKind::Lifetime(n) => (chalk_ir::VariableKind::Lifetime, n),
VariableKind::Const(ref n) => (chalk_ir::VariableKind::Const(get_type_of_u32()), n),
};
Expand Down
2 changes: 1 addition & 1 deletion chalk-integration/src/program.rs
Expand Up @@ -460,7 +460,7 @@ impl RustIrDatabase<ChalkIr> for Program {
.skip_binders()
.trait_ref
.self_type_parameter(interner);
match ty.data(interner) {
match ty.kind(interner) {
TyKind::Apply(app) => Some(app.clone()),
_ => None,
}
Expand Down
4 changes: 2 additions & 2 deletions chalk-ir/src/could_match.rs
Expand Up @@ -26,8 +26,8 @@ where
impl<'i, I: Interner> Zipper<'i, I> for MatchZipper<'i, I> {
fn zip_tys(&mut self, a: &Ty<I>, b: &Ty<I>) -> Fallible<()> {
let interner = self.interner;
let could_match = match (a.data(interner), b.data(interner)) {
(&TyKind::Apply(ref a), &TyKind::Apply(ref b)) => {
let could_match = match (a.kind(interner), b.kind(interner)) {
(TyKind::Apply(ref a), TyKind::Apply(ref b)) => {
let names_could_match = a.name == b.name;

names_could_match
Expand Down
14 changes: 12 additions & 2 deletions chalk-ir/src/debug.rs
Expand Up @@ -220,6 +220,12 @@ impl<I: Interner> Debug for TypeName<I> {
}
}

impl<I: Interner> Debug for TyData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
self.kind.fmt(fmt)
}
}

impl<I: Interner> Debug for TyKind<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
Expand Down Expand Up @@ -871,8 +877,12 @@ impl<I: Interner, T: Debug> Debug for WithKind<I, T> {
let value = self.skip_kind();
match &self.kind {
VariableKind::Ty(TyVariableKind::General) => write!(fmt, "{:?} with kind type", value),
VariableKind::Ty(TyVariableKind::Integer) => write!(fmt, "{:?} with kind integer type", value),
VariableKind::Ty(TyVariableKind::Float) => write!(fmt, "{:?} with kind float type", value),
VariableKind::Ty(TyVariableKind::Integer) => {
write!(fmt, "{:?} with kind integer type", value)
}
VariableKind::Ty(TyVariableKind::Float) => {
write!(fmt, "{:?} with kind float type", value)
}
VariableKind::Lifetime => write!(fmt, "{:?} with kind lifetime", value),
VariableKind::Const(ty) => write!(fmt, "{:?} with kind {:?}", value, ty),
}
Expand Down
2 changes: 1 addition & 1 deletion chalk-ir/src/fold.rs
Expand Up @@ -407,7 +407,7 @@ where
TI: 'i,
{
let interner = folder.interner();
match self.data(interner) {
match self.kind(interner) {
TyKind::BoundVar(bound_var) => {
if let Some(bound_var1) = bound_var.shifted_out_to(outer_binder) {
// This variable was bound outside of the binders
Expand Down
6 changes: 3 additions & 3 deletions chalk-ir/src/interner.rs
Expand Up @@ -32,7 +32,7 @@ use crate::SeparatorTraitRef;
use crate::Substitution;
use crate::TraitId;
use crate::Ty;
use crate::TyKind;
use crate::TyData;
use crate::VariableKind;
use crate::VariableKinds;
use crate::{Const, ConstData};
Expand Down Expand Up @@ -460,10 +460,10 @@ pub trait Interner: Debug + Copy + Eq + Ord + Hash {
/// Create an "interned" type from `ty`. This is not normally
/// invoked directly; instead, you invoke `TyKind::intern` (which
/// will ultimately call this method).
fn intern_ty(&self, ty: TyKind<Self>) -> Self::InternedType;
fn intern_ty(&self, ty: TyData<Self>) -> Self::InternedType;

/// Lookup the `TyKind` from an interned type.
fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a TyKind<Self>;
fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a TyData<Self>;

/// Create an "interned" lifetime from `lifetime`. This is not
/// normally invoked directly; instead, you invoke
Expand Down
38 changes: 27 additions & 11 deletions chalk-ir/src/lib.rs
Expand Up @@ -391,8 +391,11 @@ pub struct Ty<I: Interner> {
impl<I: Interner> Ty<I> {
/// Creates a type from `TyKind`.
pub fn new(interner: &I, data: impl CastTo<TyKind<I>>) -> Self {
let data = TyData {
kind: data.cast(interner),
};
Ty {
interned: I::intern_ty(interner, data.cast(interner)),
interned: I::intern_ty(interner, data),
}
}

Expand All @@ -402,10 +405,15 @@ impl<I: Interner> Ty<I> {
}

/// Gets the underlying type data.
pub fn data(&self, interner: &I) -> &TyKind<I> {
pub fn data(&self, interner: &I) -> &TyData<I> {
I::ty_data(interner, &self.interned)
}

/// Gets the underlying type kind.
pub fn kind(&self, interner: &I) -> &TyKind<I> {
&I::ty_data(interner, &self.interned).kind
}

/// Creates a `FromEnv` constraint using this type.
pub fn from_env(&self) -> FromEnv<I> {
FromEnv::Ty(self.clone())
Expand All @@ -423,7 +431,7 @@ impl<I: Interner> Ty<I> {

/// If this is a `TyKind::BoundVar(d)`, returns `Some(d)` else `None`.
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
if let TyKind::BoundVar(bv) = self.data(interner) {
if let TyKind::BoundVar(bv) = &self.data(interner).kind {
Some(*bv)
} else {
None
Expand All @@ -432,7 +440,7 @@ impl<I: Interner> Ty<I> {

/// If this is a `TyKind::InferenceVar(d)`, returns `Some(d)` else `None`.
pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
if let TyKind::InferenceVar(depth, _) = self.data(interner) {
if let TyKind::InferenceVar(depth, _) = &self.data(interner).kind {
Some(*depth)
} else {
None
Expand All @@ -441,10 +449,11 @@ impl<I: Interner> Ty<I> {

/// Returns true if this is a `BoundVar` or an `InferenceVar` of `TyVariableKind::General`.
pub fn is_general_var(&self, interner: &I, binders: &CanonicalVarKinds<I>) -> bool {
match self.data(interner) {
match &self.data(interner).kind {
TyKind::BoundVar(bv)
if bv.debruijn == DebruijnIndex::INNERMOST
&& binders.at(interner, bv.index).kind == VariableKind::Ty(TyVariableKind::General) =>
&& binders.at(interner, bv.index).kind
== VariableKind::Ty(TyVariableKind::General) =>
{
true
}
Expand All @@ -455,15 +464,15 @@ impl<I: Interner> Ty<I> {

/// Returns true if this is an `Alias`.
pub fn is_alias(&self, interner: &I) -> bool {
match self.data(interner) {
match &self.data(interner).kind {
TyKind::Alias(..) => true,
_ => false,
}
}

/// Returns true if this is an `IntTy` or `UintTy`.
pub fn is_integer(&self, interner: &I) -> bool {
match self.data(interner) {
match &self.data(interner).kind {
TyKind::Apply(ApplicationTy {
name: TypeName::Scalar(Scalar::Int(_)),
..
Expand All @@ -478,7 +487,7 @@ impl<I: Interner> Ty<I> {

/// Returns true if this is a `FloatTy`.
pub fn is_float(&self, interner: &I) -> bool {
match self.data(interner) {
match &self.data(interner).kind {
TyKind::Apply(ApplicationTy {
name: TypeName::Scalar(Scalar::Float(_)),
..
Expand All @@ -489,7 +498,7 @@ impl<I: Interner> Ty<I> {

/// Returns `Some(adt_id)` if this is an ADT, `None` otherwise
pub fn adt_id(&self, interner: &I) -> Option<AdtId<I>> {
match self.data(interner) {
match &self.data(interner).kind {
TyKind::Apply(ApplicationTy {
name: TypeName::Adt(adt_id),
..
Expand All @@ -506,6 +515,13 @@ impl<I: Interner> Ty<I> {
}
}

/// Contains the data for a Ty
#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
pub struct TyData<I: Interner> {
/// The kind
pub kind: TyKind<I>,
}

/// Type data, which holds the actual type information.
#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
pub enum TyKind<I: Interner> {
Expand Down Expand Up @@ -2431,7 +2447,7 @@ impl<I: Interner> Substitution<I> {
self.iter(interner).zip(0..).all(|(generic_arg, index)| {
let index_db = BoundVar::new(DebruijnIndex::INNERMOST, index);
match generic_arg.data(interner) {
GenericArgData::Ty(ty) => match ty.data(interner) {
GenericArgData::Ty(ty) => match &ty.data(interner).kind {
TyKind::BoundVar(depth) => index_db == *depth,
_ => false,
},
Expand Down
2 changes: 1 addition & 1 deletion chalk-ir/src/visit.rs
Expand Up @@ -272,7 +272,7 @@ where
I: 'i,
{
let interner = visitor.interner();
match self.data(interner) {
match self.kind(interner) {
TyKind::BoundVar(bound_var) => {
if let Some(_) = bound_var.shifted_out_to(outer_binder) {
visitor.visit_free_var(*bound_var, outer_binder)
Expand Down
16 changes: 8 additions & 8 deletions chalk-solve/src/clauses.rs
Expand Up @@ -382,7 +382,7 @@ fn program_clauses_that_could_match<I: Interner>(
if trait_datum.is_non_enumerable_trait() || trait_datum.is_auto_trait() {
let self_ty = trait_ref.self_type_parameter(interner);

if let TyKind::Alias(AliasTy::Opaque(opaque_ty)) = self_ty.data(interner) {
if let TyKind::Alias(AliasTy::Opaque(opaque_ty)) = self_ty.kind(interner) {
if trait_datum.is_auto_trait() {
push_auto_trait_impls_opaque(builder, trait_id, opaque_ty.opaque_ty_id)
}
Expand Down Expand Up @@ -411,7 +411,7 @@ fn program_clauses_that_could_match<I: Interner>(
let generalized = generalize::Generalize::apply(db.interner(), trait_ref);
builder.push_binders(&generalized, |builder, trait_ref| {
let ty = trait_ref.self_type_parameter(interner);
match ty.data(interner) {
match ty.kind(interner) {
TyKind::Apply(apply) => {
push_auto_trait_impls(builder, trait_id, apply);
Ok(())
Expand Down Expand Up @@ -444,11 +444,11 @@ fn program_clauses_that_could_match<I: Interner>(
// totally irrelevant to that goal, because they let us prove other
// things but not `Clone`.
let self_ty = trait_ref.self_type_parameter(interner);
if let TyKind::Dyn(_) = self_ty.data(interner) {
if let TyKind::Dyn(_) = self_ty.kind(interner) {
dyn_ty::build_dyn_self_ty_clauses(db, builder, self_ty.clone())
}

match self_ty.data(interner) {
match self_ty.kind(interner) {
TyKind::Apply(ApplicationTy {
name: TypeName::OpaqueType(opaque_ty_id),
..
Expand All @@ -461,7 +461,7 @@ fn program_clauses_that_could_match<I: Interner>(
}

// We don't actually do anything here, but we need to record the types it when logging
match self_ty.data(interner) {
match self_ty.kind(interner) {
TyKind::Apply(ApplicationTy {
name: TypeName::Adt(adt_id),
..
Expand Down Expand Up @@ -489,7 +489,7 @@ fn program_clauses_that_could_match<I: Interner>(
.trait_ref_from_projection(proj)
.self_type_parameter(interner);

match trait_self_ty.data(interner) {
match trait_self_ty.kind(interner) {
TyKind::Apply(ApplicationTy {
name: TypeName::OpaqueType(opaque_ty_id),
..
Expand All @@ -504,7 +504,7 @@ fn program_clauses_that_could_match<I: Interner>(
// If the self type is a `dyn trait` type, generate program-clauses
// for any associated type bindings it contains.
// FIXME: see the fixme for the analogous code for Implemented goals.
if let TyKind::Dyn(_) = trait_self_ty.data(interner) {
if let TyKind::Dyn(_) = trait_self_ty.kind(interner) {
dyn_ty::build_dyn_self_ty_clauses(db, builder, trait_self_ty.clone())
}

Expand Down Expand Up @@ -740,7 +740,7 @@ fn match_ty<I: Interner>(
ty: &Ty<I>,
) -> Result<(), Floundered> {
let interner = builder.interner();
Ok(match ty.data(interner) {
Ok(match ty.kind(interner) {
TyKind::Apply(application_ty) => match_type_name(builder, environment, application_ty),
TyKind::Placeholder(_) => {
builder.push_clause(WellFormed::Ty(ty.clone()), Some(FromEnv::Ty(ty.clone())));
Expand Down

0 comments on commit 5452311

Please sign in to comment.