From bfbc210bc1216b79e355eb70449caf08dc67d5ad Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 22 May 2020 18:15:53 +0200 Subject: Use Chalk's built-in representation of function item types --- crates/ra_hir_ty/src/traits/chalk/interner.rs | 2 ++ crates/ra_hir_ty/src/traits/chalk/mapping.rs | 26 ++++++++++++++++++++++---- crates/ra_hir_ty/src/traits/chalk/tls.rs | 18 ++++++++++++++++-- 3 files changed, 40 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_ty/src/traits/chalk') diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs index 060372819..2a27f8ed8 100644 --- a/crates/ra_hir_ty/src/traits/chalk/interner.rs +++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs @@ -20,6 +20,8 @@ pub type ImplId = chalk_ir::ImplId; pub type ImplDatum = chalk_rust_ir::ImplDatum; pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue; +pub type FnDefId = chalk_ir::FnDefId; +pub type FnDefDatum = chalk_rust_ir::FnDefDatum; impl chalk_ir::interner::Interner for Interner { type InternedType = Box>; // FIXME use Arc? diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index a83d82fd8..7841a0e21 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -15,8 +15,8 @@ use crate::{ db::HirDatabase, primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, - ApplicationTy, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, Substs, - TraitEnvironment, TraitRef, Ty, TypeCtor, + ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, + Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, }; use super::interner::*; @@ -217,11 +217,14 @@ impl ToChalk for TypeCtor { TypeCtor::Slice => TypeName::Slice, TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), TypeCtor::Str => TypeName::Str, + TypeCtor::FnDef(callable_def) => { + let id = callable_def.to_chalk(db); + TypeName::FnDef(id) + } TypeCtor::Int(Uncertain::Unknown) | TypeCtor::Float(Uncertain::Unknown) | TypeCtor::Adt(_) | TypeCtor::Array - | TypeCtor::FnDef(_) | TypeCtor::FnPtr { .. } | TypeCtor::Never | TypeCtor::Closure { .. } => { @@ -260,7 +263,10 @@ impl ToChalk for TypeCtor { TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)), TypeName::Str => TypeCtor::Str, - TypeName::FnDef(_) => unreachable!(), + TypeName::FnDef(fn_def_id) => { + let callable_def = from_chalk(db, fn_def_id); + TypeCtor::FnDef(callable_def) + } TypeName::Error => { // this should not be reached, since we don't represent TypeName::Error with TypeCtor @@ -347,6 +353,18 @@ impl ToChalk for Impl { } } +impl ToChalk for CallableDef { + type Chalk = FnDefId; + + fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { + db.intern_callable_def(self).into() + } + + fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef { + db.lookup_intern_callable_def(fn_def_id.into()) + } +} + impl ToChalk for TypeAliasId { type Chalk = AssocTypeId; diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs index ebf402a07..d88828c7c 100644 --- a/crates/ra_hir_ty/src/traits/chalk/tls.rs +++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs @@ -247,10 +247,24 @@ impl DebugContext<'_> { pub fn debug_fn_def_id( &self, - _fn_def_id: chalk_ir::FnDefId, + fn_def_id: chalk_ir::FnDefId, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { - write!(fmt, "fn") + let def: CallableDef = from_chalk(self.0, fn_def_id); + let name = match def { + CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), + CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), + CallableDef::EnumVariantId(e) => { + let enum_data = self.0.enum_data(e.parent); + enum_data.variants[e.local_id].name.clone() + } + }; + match def { + CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name), + CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { + write!(fmt, "{{ctor {}}}", name) + } + } } pub fn debug_const( -- cgit v1.2.3 From 194dd9eb0d44284f7e952a1e84296fcda4d90f5e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 22 May 2020 19:13:17 +0200 Subject: Use Chalk's Ty::Function for function pointer types Function pointers can be 'higher-ranked' over lifetimes, which is why they're not an application type in Chalk, but since we don't model lifetimes it doesn't matter for us yet. --- crates/ra_hir_ty/src/traits/chalk/mapping.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_ty/src/traits/chalk') diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 7841a0e21..7082cb095 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -26,14 +26,19 @@ impl ToChalk for Ty { type Chalk = chalk_ir::Ty; fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { match self { - Ty::Apply(apply_ty) => { - if let TypeCtor::Ref(m) = apply_ty.ctor { - return ref_to_chalk(db, m, apply_ty.parameters); + Ty::Apply(apply_ty) => match apply_ty.ctor { + TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), + TypeCtor::FnPtr { num_args: _ } => { + let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); + chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) + .intern(&Interner) } - let name = apply_ty.ctor.to_chalk(db); - let substitution = apply_ty.parameters.to_chalk(db); - chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) - } + _ => { + let name = apply_ty.ctor.to_chalk(db); + let substitution = apply_ty.parameters.to_chalk(db); + chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) + } + }, Ty::Projection(proj_ty) => { let associated_ty_id = proj_ty.associated_ty.to_chalk(db); let substitution = proj_ty.parameters.to_chalk(db); @@ -93,7 +98,13 @@ impl ToChalk for Ty { Ty::Projection(ProjectionTy { associated_ty, parameters }) } chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), - chalk_ir::TyData::Function(_) => unimplemented!(), + chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { + let parameters: Substs = from_chalk(db, substitution); + Ty::Apply(ApplicationTy { + ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, + parameters, + }) + } chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, chalk_ir::TyData::Dyn(where_clauses) => { -- cgit v1.2.3 From c8a4bb1445e214dc7105de547bd999ad270e7b42 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 27 May 2020 21:05:21 +0200 Subject: Upgrade Chalk Chalk newly added TypeName::Never and Array; I implemented the conversion for Never, but not Array since that expects a const argument. --- crates/ra_hir_ty/src/traits/chalk/interner.rs | 14 +++++----- crates/ra_hir_ty/src/traits/chalk/mapping.rs | 40 +++++++++++++-------------- 2 files changed, 27 insertions(+), 27 deletions(-) (limited to 'crates/ra_hir_ty/src/traits/chalk') diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs index 2a27f8ed8..e27074ba6 100644 --- a/crates/ra_hir_ty/src/traits/chalk/interner.rs +++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs @@ -11,17 +11,17 @@ use std::{fmt, sync::Arc}; pub struct Interner; pub type AssocTypeId = chalk_ir::AssocTypeId; -pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum; +pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum; pub type TraitId = chalk_ir::TraitId; -pub type TraitDatum = chalk_rust_ir::TraitDatum; +pub type TraitDatum = chalk_solve::rust_ir::TraitDatum; pub type AdtId = chalk_ir::AdtId; -pub type StructDatum = chalk_rust_ir::AdtDatum; +pub type StructDatum = chalk_solve::rust_ir::AdtDatum; pub type ImplId = chalk_ir::ImplId; -pub type ImplDatum = chalk_rust_ir::ImplDatum; -pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; -pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue; +pub type ImplDatum = chalk_solve::rust_ir::ImplDatum; +pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId; +pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue; pub type FnDefId = chalk_ir::FnDefId; -pub type FnDefDatum = chalk_rust_ir::FnDefDatum; +pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum; impl chalk_ir::interner::Interner for Interner { type InternedType = Box>; // FIXME use Arc? diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 7082cb095..5f6daf842 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -7,6 +7,7 @@ use chalk_ir::{ cast::Cast, fold::shift::Shift, interner::HasInterner, PlaceholderIndex, Scalar, TypeName, UniverseIndex, }; +use chalk_solve::rust_ir; use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, TypeAliasId}; use ra_db::salsa::InternKey; @@ -106,7 +107,7 @@ impl ToChalk for Ty { }) } chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), - chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, + chalk_ir::TyData::InferenceVar(_iv, _kind) => Ty::Unknown, chalk_ir::TyData::Dyn(where_clauses) => { assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); let predicates = where_clauses @@ -232,12 +233,13 @@ impl ToChalk for TypeCtor { let id = callable_def.to_chalk(db); TypeName::FnDef(id) } + TypeCtor::Never => TypeName::Never, + TypeCtor::Int(Uncertain::Unknown) | TypeCtor::Float(Uncertain::Unknown) | TypeCtor::Adt(_) | TypeCtor::Array | TypeCtor::FnPtr { .. } - | TypeCtor::Never | TypeCtor::Closure { .. } => { // other TypeCtors get interned and turned into a chalk StructId let struct_id = db.intern_type_ctor(self).into(); @@ -273,13 +275,14 @@ impl ToChalk for TypeCtor { TypeName::Slice => TypeCtor::Slice, TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)), TypeName::Str => TypeCtor::Str, + TypeName::Never => TypeCtor::Never, TypeName::FnDef(fn_def_id) => { let callable_def = from_chalk(db, fn_def_id); TypeCtor::FnDef(callable_def) } - TypeName::Error => { + TypeName::Array | TypeName::Error => { // this should not be reached, since we don't represent TypeName::Error with TypeCtor unreachable!() } @@ -508,7 +511,7 @@ where fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical { let parameter = chalk_ir::CanonicalVarKind::new( - chalk_ir::VariableKind::Ty, + chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General), chalk_ir::UniverseIndex::ROOT, ); let value = self.value.to_chalk(db); @@ -579,17 +582,17 @@ impl ToChalk for builtin::BuiltinImplData { type Chalk = ImplDatum; fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum { - let impl_type = chalk_rust_ir::ImplType::External; + let impl_type = rust_ir::ImplType::External; let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect(); let impl_datum_bound = - chalk_rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses }; + rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses }; let associated_ty_value_ids = self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect(); - chalk_rust_ir::ImplDatum { + rust_ir::ImplDatum { binders: make_binders(impl_datum_bound, self.num_vars), impl_type, - polarity: chalk_rust_ir::Polarity::Positive, + polarity: rust_ir::Polarity::Positive, associated_ty_value_ids, } } @@ -604,9 +607,9 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData { fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue { let ty = self.value.to_chalk(db); - let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty }; + let value_bound = rust_ir::AssociatedTyValueBound { ty }; - chalk_rust_ir::AssociatedTyValue { + rust_ir::AssociatedTyValue { associated_ty_id: self.assoc_ty_id.to_chalk(db), impl_id: self.impl_.to_chalk(db), value: make_binders(value_bound, self.num_vars), @@ -628,7 +631,7 @@ where chalk_ir::Binders::new( chalk_ir::VariableKinds::from( &Interner, - std::iter::repeat(chalk_ir::VariableKind::Ty).take(num_vars), + std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), ), value, ) @@ -655,7 +658,7 @@ pub(super) fn generic_predicate_to_inline_bound( db: &dyn HirDatabase, pred: &GenericPredicate, self_ty: &Ty, -) -> Option> { +) -> Option> { // An InlineBound is like a GenericPredicate, except the self type is left out. // We don't have a special type for this, but Chalk does. match pred { @@ -670,8 +673,8 @@ pub(super) fn generic_predicate_to_inline_bound( .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) .collect(); let trait_bound = - chalk_rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self }; - Some(chalk_rust_ir::InlineBound::TraitBound(trait_bound)) + rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self }; + Some(rust_ir::InlineBound::TraitBound(trait_bound)) } GenericPredicate::Projection(proj) => { if &proj.projection_ty.parameters[0] != self_ty { @@ -685,16 +688,13 @@ pub(super) fn generic_predicate_to_inline_bound( .iter() .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) .collect(); - let alias_eq_bound = chalk_rust_ir::AliasEqBound { + let alias_eq_bound = rust_ir::AliasEqBound { value: proj.ty.clone().to_chalk(db), - trait_bound: chalk_rust_ir::TraitBound { - trait_id: trait_.to_chalk(db), - args_no_self, - }, + trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, associated_ty_id: proj.projection_ty.associated_ty.to_chalk(db), parameters: Vec::new(), // FIXME we don't support generic associated types yet }; - Some(chalk_rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) + Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) } GenericPredicate::Error => None, } -- cgit v1.2.3