From 67a2555f6d4c3914742fd42645ca043cf56f358b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 21 Dec 2019 14:29:33 +0100 Subject: Update Chalk, clean up Chalk integration a bit --- crates/ra_hir_ty/Cargo.toml | 7 +- crates/ra_hir_ty/src/db.rs | 35 ++----- crates/ra_hir_ty/src/traits.rs | 6 +- crates/ra_hir_ty/src/traits/chalk.rs | 180 +++++++++++++++++------------------ 4 files changed, 103 insertions(+), 125 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index d277bf2bc..60793db44 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml @@ -21,10 +21,9 @@ ra_prof = { path = "../ra_prof" } ra_syntax = { path = "../ra_syntax" } test_utils = { path = "../test_utils" } -# https://github.com/rust-lang/chalk/pull/294 -chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } -chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } +chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" } +chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" } +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" } lalrpop-intern = "0.15.1" diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index 222a36a9f..d52f65b83 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs @@ -10,7 +10,7 @@ use ra_db::{salsa, CrateId}; use crate::{ method_resolution::CrateImplBlocks, - traits::{AssocTyValue, Impl}, + traits::{chalk, AssocTyValue, Impl}, CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor, ValueTyDefId, }; @@ -77,39 +77,24 @@ pub trait HirDatabase: DefDatabase { #[salsa::interned] fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; - #[salsa::invoke(crate::traits::chalk::associated_ty_data_query)] - fn associated_ty_data( - &self, - id: chalk_ir::TypeId, - ) -> Arc>; + #[salsa::invoke(chalk::associated_ty_data_query)] + fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc; - #[salsa::invoke(crate::traits::chalk::trait_datum_query)] - fn trait_datum( - &self, - krate: CrateId, - trait_id: chalk_ir::TraitId, - ) -> Arc>; + #[salsa::invoke(chalk::trait_datum_query)] + fn trait_datum(&self, krate: CrateId, trait_id: chalk::TraitId) -> Arc; - #[salsa::invoke(crate::traits::chalk::struct_datum_query)] - fn struct_datum( - &self, - krate: CrateId, - struct_id: chalk_ir::StructId, - ) -> Arc>; + #[salsa::invoke(chalk::struct_datum_query)] + fn struct_datum(&self, krate: CrateId, struct_id: chalk::StructId) -> Arc; #[salsa::invoke(crate::traits::chalk::impl_datum_query)] - fn impl_datum( - &self, - krate: CrateId, - impl_id: chalk_ir::ImplId, - ) -> Arc>; + fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc; #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] fn associated_ty_value( &self, krate: CrateId, - id: chalk_rust_ir::AssociatedTyValueId, - ) -> Arc>; + id: chalk::AssociatedTyValueId, + ) -> Arc; #[salsa::invoke(crate::traits::trait_solve_query)] fn trait_solve( diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index d49f8fb4b..46e17f0b8 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs @@ -209,9 +209,9 @@ fn solution_from_chalk( .parameters .into_iter() .map(|p| { - let ty = match p { - chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), - chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), + let ty = match p.ty() { + Some(ty) => from_chalk(db, ty.clone()), + None => unimplemented!(), }; ty }) diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 5eb032d86..3a91a374d 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -3,15 +3,9 @@ use std::sync::Arc; use log::debug; -use chalk_ir::{ - cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId, - TypeName, UniverseIndex, -}; -use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; +use chalk_ir::{cast::Cast, family::ChalkIr, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; -use hir_def::{ - AssocContainerId, AssocItemId, GenericDefId, HasModule, ImplId, Lookup, TraitId, TypeAliasId, -}; +use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; use ra_db::{ salsa::{InternId, InternKey}, CrateId, @@ -23,9 +17,20 @@ use crate::{ ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, }; +pub type TypeFamily = chalk_ir::family::ChalkIr; // TODO use everywhere +pub type AssocTypeId = chalk_ir::AssocTypeId; +pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum; +pub type TraitId = chalk_ir::TraitId; +pub type TraitDatum = chalk_rust_ir::TraitDatum; +pub type StructId = chalk_ir::StructId; +pub type StructDatum = chalk_rust_ir::StructDatum; +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; + /// This represents a trait whose name we could not resolve. -const UNKNOWN_TRAIT: chalk_ir::TraitId = - chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); +const UNKNOWN_TRAIT: TraitId = chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); pub(super) trait ToChalk { type Chalk; @@ -53,7 +58,7 @@ impl ToChalk for Ty { _ => { // other TypeCtors get interned and turned into a chalk StructId let struct_id = apply_ty.ctor.to_chalk(db); - TypeName::TypeKindId(struct_id.into()) + TypeName::Struct(struct_id.into()) } }; let parameters = apply_ty.parameters.to_chalk(db); @@ -71,11 +76,13 @@ impl ToChalk for Ty { Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), Ty::Dyn(predicates) => { let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); - chalk_ir::TyData::Dyn(make_binders(where_clauses, 1)).intern() + let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) }; + chalk_ir::TyData::Dyn(bounded_ty).intern() } Ty::Opaque(predicates) => { let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); - chalk_ir::TyData::Opaque(make_binders(where_clauses, 1)).intern() + let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) }; + chalk_ir::TyData::Opaque(bounded_ty).intern() } Ty::Unknown => { let parameters = Vec::new(); @@ -87,10 +94,9 @@ impl ToChalk for Ty { fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { match chalk.data().clone() { chalk_ir::TyData::Apply(apply_ty) => { - // FIXME this is kind of hacky due to the fact that - // TypeName::Placeholder is a Ty::Param on our side + // TODO clean this up now that Placeholder isn't in TypeName anymore match apply_ty.name { - TypeName::TypeKindId(TypeKindId::StructId(struct_id)) => { + TypeName::Struct(struct_id) => { let ctor = from_chalk(db, struct_id); let parameters = from_chalk(db, apply_ty.parameters); Ty::Apply(ApplicationTy { ctor, parameters }) @@ -101,14 +107,12 @@ impl ToChalk for Ty { Ty::Apply(ApplicationTy { ctor, parameters }) } TypeName::Error => Ty::Unknown, - // FIXME handle TypeKindId::Trait/Type here - TypeName::TypeKindId(_) => unimplemented!(), - TypeName::Placeholder(idx) => { - assert_eq!(idx.ui, UniverseIndex::ROOT); - Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } - } } } + chalk_ir::TyData::Placeholder(idx) => { + assert_eq!(idx.ui, UniverseIndex::ROOT); + Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } + } chalk_ir::TyData::Projection(proj) => { let associated_ty = from_chalk(db, proj.associated_ty_id); let parameters = from_chalk(db, proj.parameters); @@ -118,15 +122,15 @@ impl ToChalk for Ty { chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, chalk_ir::TyData::Dyn(where_clauses) => { - assert_eq!(where_clauses.binders.len(), 1); + assert_eq!(where_clauses.bounds.binders.len(), 1); let predicates = - where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); + where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect(); Ty::Dyn(predicates) } chalk_ir::TyData::Opaque(where_clauses) => { - assert_eq!(where_clauses.binders.len(), 1); + assert_eq!(where_clauses.bounds.binders.len(), 1); let predicates = - where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); + where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect(); Ty::Opaque(predicates) } } @@ -143,9 +147,9 @@ impl ToChalk for Substs { fn from_chalk(db: &impl HirDatabase, parameters: Vec>) -> Substs { let tys = parameters .into_iter() - .map(|p| match p { - chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), - chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), + .map(|p| match p.ty() { + Some(ty) => from_chalk(db, ty.clone()), + None => unimplemented!(), }) .collect(); Substs(tys) @@ -168,65 +172,62 @@ impl ToChalk for TraitRef { } } -impl ToChalk for TraitId { - type Chalk = chalk_ir::TraitId; +impl ToChalk for hir_def::TraitId { + type Chalk = TraitId; - fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { + fn to_chalk(self, _db: &impl HirDatabase) -> TraitId { chalk_ir::TraitId(id_to_chalk(self)) } - fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId { + fn from_chalk(_db: &impl HirDatabase, trait_id: TraitId) -> hir_def::TraitId { id_from_chalk(trait_id.0) } } impl ToChalk for TypeCtor { - type Chalk = chalk_ir::StructId; + type Chalk = StructId; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::StructId { + fn to_chalk(self, db: &impl HirDatabase) -> StructId { db.intern_type_ctor(self).into() } - fn from_chalk(db: &impl HirDatabase, struct_id: chalk_ir::StructId) -> TypeCtor { + fn from_chalk(db: &impl HirDatabase, struct_id: StructId) -> TypeCtor { db.lookup_intern_type_ctor(struct_id.into()) } } impl ToChalk for Impl { - type Chalk = chalk_ir::ImplId; + type Chalk = ImplId; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ImplId { + fn to_chalk(self, db: &impl HirDatabase) -> ImplId { db.intern_chalk_impl(self).into() } - fn from_chalk(db: &impl HirDatabase, impl_id: chalk_ir::ImplId) -> Impl { + fn from_chalk(db: &impl HirDatabase, impl_id: ImplId) -> Impl { db.lookup_intern_chalk_impl(impl_id.into()) } } impl ToChalk for TypeAliasId { - type Chalk = chalk_ir::TypeId; + type Chalk = AssocTypeId; - fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { - chalk_ir::TypeId(id_to_chalk(self)) + fn to_chalk(self, _db: &impl HirDatabase) -> AssocTypeId { + chalk_ir::AssocTypeId(id_to_chalk(self)) } - fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId { + fn from_chalk(_db: &impl HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId { id_from_chalk(type_alias_id.0) } } impl ToChalk for AssocTyValue { - type Chalk = chalk_rust_ir::AssociatedTyValueId; + type Chalk = AssociatedTyValueId; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValueId { + fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValueId { db.intern_assoc_ty_value(self).into() } - fn from_chalk( - db: &impl HirDatabase, - assoc_ty_value_id: chalk_rust_ir::AssociatedTyValueId, - ) -> AssocTyValue { + fn from_chalk(db: &impl HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) } } @@ -468,28 +469,28 @@ impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> where DB: HirDatabase, { - fn associated_ty_data(&self, id: TypeId) -> Arc> { + fn associated_ty_data(&self, id: AssocTypeId) -> Arc { self.db.associated_ty_data(id) } - fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc> { + fn trait_datum(&self, trait_id: TraitId) -> Arc { self.db.trait_datum(self.krate, trait_id) } - fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc> { + fn struct_datum(&self, struct_id: StructId) -> Arc { self.db.struct_datum(self.krate, struct_id) } - fn impl_datum(&self, impl_id: chalk_ir::ImplId) -> Arc> { + fn impl_datum(&self, impl_id: ImplId) -> Arc { self.db.impl_datum(self.krate, impl_id) } fn impls_for_trait( &self, - trait_id: chalk_ir::TraitId, - parameters: &[Parameter], - ) -> Vec { + trait_id: TraitId, + parameters: &[Parameter], + ) -> Vec { debug!("impls_for_trait {:?}", trait_id); if trait_id == UNKNOWN_TRAIT { return Vec::new(); } - let trait_: TraitId = from_chalk(self.db, trait_id); + let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); let mut result: Vec<_> = self .db .impls_for_trait(self.krate, trait_.into()) @@ -508,39 +509,32 @@ where debug!("impls_for_trait returned {} impls", result.len()); result } - fn impl_provided_for( - &self, - auto_trait_id: chalk_ir::TraitId, - struct_id: chalk_ir::StructId, - ) -> bool { + fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: StructId) -> bool { debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id); false // FIXME } - fn type_name(&self, _id: TypeKindId) -> Identifier { - unimplemented!() - } - fn associated_ty_value( - &self, - id: chalk_rust_ir::AssociatedTyValueId, - ) -> Arc> { + fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc { self.db.associated_ty_value(self.krate.into(), id) } fn custom_clauses(&self) -> Vec> { vec![] } - fn local_impls_to_coherence_check( - &self, - _trait_id: chalk_ir::TraitId, - ) -> Vec { + fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec { // We don't do coherence checking (yet) unimplemented!() } + fn as_struct_id(&self, id: &TypeName) -> Option { + match id { + TypeName::Struct(struct_id) => Some(*struct_id), + _ => None, + } + } } pub(crate) fn associated_ty_data_query( db: &impl HirDatabase, - id: TypeId, -) -> Arc> { + id: AssocTypeId, +) -> Arc { debug!("associated_ty_data {:?}", id); let type_alias: TypeAliasId = from_chalk(db, id); let trait_ = match type_alias.lookup(db).container { @@ -565,8 +559,8 @@ pub(crate) fn associated_ty_data_query( pub(crate) fn trait_datum_query( db: &impl HirDatabase, krate: CrateId, - trait_id: chalk_ir::TraitId, -) -> Arc> { + trait_id: TraitId, +) -> Arc { debug!("trait_datum {:?}", trait_id); if trait_id == UNKNOWN_TRAIT { let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses: Vec::new() }; @@ -586,7 +580,7 @@ pub(crate) fn trait_datum_query( associated_ty_ids: vec![], }); } - let trait_: TraitId = from_chalk(db, trait_id); + let trait_: hir_def::TraitId = from_chalk(db, trait_id); let trait_data = db.trait_data(trait_); debug!("trait {:?} = {:?}", trait_id, trait_data.name); let generic_params = generics(db, trait_.into()); @@ -616,8 +610,8 @@ pub(crate) fn trait_datum_query( pub(crate) fn struct_datum_query( db: &impl HirDatabase, krate: CrateId, - struct_id: chalk_ir::StructId, -) -> Arc> { + struct_id: StructId, +) -> Arc { debug!("struct_datum {:?}", struct_id); let type_ctor: TypeCtor = from_chalk(db, struct_id); debug!("struct {:?} = {:?}", struct_id, type_ctor); @@ -648,8 +642,8 @@ pub(crate) fn struct_datum_query( pub(crate) fn impl_datum_query( db: &impl HirDatabase, krate: CrateId, - impl_id: chalk_ir::ImplId, -) -> Arc> { + impl_id: ImplId, +) -> Arc { let _p = ra_prof::profile("impl_datum"); debug!("impl_datum {:?}", impl_id); let impl_: Impl = from_chalk(db, impl_id); @@ -663,9 +657,9 @@ pub(crate) fn impl_datum_query( fn impl_block_datum( db: &impl HirDatabase, krate: CrateId, - chalk_id: chalk_ir::ImplId, - impl_id: ImplId, -) -> Option>> { + chalk_id: ImplId, + impl_id: hir_def::ImplId, +) -> Option> { let trait_ref = db.impl_trait(impl_id)?; let impl_data = db.impl_data(impl_id); @@ -721,7 +715,7 @@ fn impl_block_datum( Some(Arc::new(impl_datum)) } -fn invalid_impl_datum() -> Arc> { +fn invalid_impl_datum() -> Arc { let trait_ref = chalk_ir::TraitRef { trait_id: UNKNOWN_TRAIT, parameters: vec![chalk_ir::TyData::BoundVar(0).cast().intern().cast()], @@ -754,7 +748,7 @@ fn type_alias_associated_ty_value( db: &impl HirDatabase, _krate: CrateId, type_alias: TypeAliasId, -) -> Arc> { +) -> Arc { let type_alias_data = db.type_alias_data(type_alias); let impl_id = match type_alias.lookup(db).container { AssocContainerId::ImplId(it) => it, @@ -786,25 +780,25 @@ fn id_to_chalk(salsa_id: T) -> chalk_ir::RawId { chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } } -impl From for crate::TypeCtorId { - fn from(struct_id: chalk_ir::StructId) -> Self { +impl From for crate::TypeCtorId { + fn from(struct_id: StructId) -> Self { id_from_chalk(struct_id.0) } } -impl From for chalk_ir::StructId { +impl From for StructId { fn from(type_ctor_id: crate::TypeCtorId) -> Self { chalk_ir::StructId(id_to_chalk(type_ctor_id)) } } -impl From for crate::traits::GlobalImplId { - fn from(impl_id: chalk_ir::ImplId) -> Self { +impl From for crate::traits::GlobalImplId { + fn from(impl_id: ImplId) -> Self { id_from_chalk(impl_id.0) } } -impl From for chalk_ir::ImplId { +impl From for ImplId { fn from(impl_id: crate::traits::GlobalImplId) -> Self { chalk_ir::ImplId(id_to_chalk(impl_id)) } -- cgit v1.2.3 From 6b5efe5bdab160278469417734f4bb619c7bac61 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 21 Dec 2019 14:46:15 +0100 Subject: Refactor Chalk integration some more --- crates/ra_hir_ty/src/traits.rs | 14 ++-- crates/ra_hir_ty/src/traits/chalk.rs | 148 ++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 79 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index 46e17f0b8..fbab60925 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs @@ -1,7 +1,7 @@ //! Trait solving using Chalk. use std::sync::{Arc, Mutex}; -use chalk_ir::{cast::Cast, family::ChalkIr}; +use chalk_ir::cast::Cast; use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId}; use log::debug; use ra_db::{impl_intern_key, salsa, CrateId}; @@ -12,7 +12,7 @@ use crate::db::HirDatabase; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; -use self::chalk::{from_chalk, ToChalk}; +use self::chalk::{from_chalk, ToChalk, TypeFamily}; pub(crate) mod chalk; mod builtin; @@ -20,7 +20,7 @@ mod builtin; #[derive(Debug, Clone)] pub struct TraitSolver { krate: CrateId, - inner: Arc>>, + inner: Arc>>, } /// We need eq for salsa @@ -36,8 +36,8 @@ impl TraitSolver { fn solve( &self, db: &impl HirDatabase, - goal: &chalk_ir::UCanonical>>, - ) -> Option> { + goal: &chalk_ir::UCanonical>>, + ) -> Option> { let context = ChalkContext { db, krate: self.krate }; debug!("solve goal: {:?}", goal); let mut solver = match self.inner.lock() { @@ -201,9 +201,9 @@ pub(crate) fn trait_solve_query( fn solution_from_chalk( db: &impl HirDatabase, - solution: chalk_solve::Solution, + solution: chalk_solve::Solution, ) -> Solution { - let convert_subst = |subst: chalk_ir::Canonical>| { + let convert_subst = |subst: chalk_ir::Canonical>| { let value = subst .value .parameters diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 3a91a374d..d53d3fdeb 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use log::debug; -use chalk_ir::{cast::Cast, family::ChalkIr, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; +use chalk_ir::{cast::Cast, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; use ra_db::{ @@ -17,7 +17,7 @@ use crate::{ ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, }; -pub type TypeFamily = chalk_ir::family::ChalkIr; // TODO use everywhere +pub type TypeFamily = chalk_ir::family::ChalkIr; pub type AssocTypeId = chalk_ir::AssocTypeId; pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum; pub type TraitId = chalk_ir::TraitId; @@ -46,21 +46,11 @@ where } impl ToChalk for Ty { - type Chalk = chalk_ir::Ty; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { + type Chalk = chalk_ir::Ty; + fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { match self { Ty::Apply(apply_ty) => { - let name = match apply_ty.ctor { - TypeCtor::AssociatedType(type_alias) => { - let type_id = type_alias.to_chalk(db); - TypeName::AssociatedType(type_id) - } - _ => { - // other TypeCtors get interned and turned into a chalk StructId - let struct_id = apply_ty.ctor.to_chalk(db); - TypeName::Struct(struct_id.into()) - } - }; + let name = apply_ty.ctor.to_chalk(db); let parameters = apply_ty.parameters.to_chalk(db); chalk_ir::ApplicationTy { name, parameters }.cast().intern() } @@ -70,7 +60,8 @@ impl ToChalk for Ty { chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern() } Ty::Param { idx, .. } => { - PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::() + PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize } + .to_ty::() } Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), @@ -91,24 +82,16 @@ impl ToChalk for Ty { } } } - fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { + fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { match chalk.data().clone() { - chalk_ir::TyData::Apply(apply_ty) => { - // TODO clean this up now that Placeholder isn't in TypeName anymore - match apply_ty.name { - TypeName::Struct(struct_id) => { - let ctor = from_chalk(db, struct_id); - let parameters = from_chalk(db, apply_ty.parameters); - Ty::Apply(ApplicationTy { ctor, parameters }) - } - TypeName::AssociatedType(type_id) => { - let ctor = TypeCtor::AssociatedType(from_chalk(db, type_id)); - let parameters = from_chalk(db, apply_ty.parameters); - Ty::Apply(ApplicationTy { ctor, parameters }) - } - TypeName::Error => Ty::Unknown, + chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { + TypeName::Error => Ty::Unknown, + _ => { + let ctor = from_chalk(db, apply_ty.name); + let parameters = from_chalk(db, apply_ty.parameters); + Ty::Apply(ApplicationTy { ctor, parameters }) } - } + }, chalk_ir::TyData::Placeholder(idx) => { assert_eq!(idx.ui, UniverseIndex::ROOT); Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } @@ -138,13 +121,16 @@ impl ToChalk for Ty { } impl ToChalk for Substs { - type Chalk = Vec>; + type Chalk = Vec>; - fn to_chalk(self, db: &impl HirDatabase) -> Vec> { + fn to_chalk(self, db: &impl HirDatabase) -> Vec> { self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() } - fn from_chalk(db: &impl HirDatabase, parameters: Vec>) -> Substs { + fn from_chalk( + db: &impl HirDatabase, + parameters: Vec>, + ) -> Substs { let tys = parameters .into_iter() .map(|p| match p.ty() { @@ -157,15 +143,15 @@ impl ToChalk for Substs { } impl ToChalk for TraitRef { - type Chalk = chalk_ir::TraitRef; + type Chalk = chalk_ir::TraitRef; - fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef { + fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef { let trait_id = self.trait_.to_chalk(db); let parameters = self.substs.to_chalk(db); chalk_ir::TraitRef { trait_id, parameters } } - fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { + fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { let trait_ = from_chalk(db, trait_ref.trait_id); let substs = from_chalk(db, trait_ref.parameters); TraitRef { trait_, substs } @@ -185,14 +171,31 @@ impl ToChalk for hir_def::TraitId { } impl ToChalk for TypeCtor { - type Chalk = StructId; + type Chalk = TypeName; - fn to_chalk(self, db: &impl HirDatabase) -> StructId { - db.intern_type_ctor(self).into() + fn to_chalk(self, db: &impl HirDatabase) -> TypeName { + match self { + TypeCtor::AssociatedType(type_alias) => { + let type_id = type_alias.to_chalk(db); + TypeName::AssociatedType(type_id) + } + _ => { + // other TypeCtors get interned and turned into a chalk StructId + let struct_id = db.intern_type_ctor(self).into(); + TypeName::Struct(struct_id) + } + } } - fn from_chalk(db: &impl HirDatabase, struct_id: StructId) -> TypeCtor { - db.lookup_intern_type_ctor(struct_id.into()) + fn from_chalk(db: &impl HirDatabase, type_name: TypeName) -> TypeCtor { + match type_name { + TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), + TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), + TypeName::Error => { + // this should not be reached, since we don't represent TypeName::Error with TypeCtor + unreachable!() + } + } } } @@ -233,9 +236,9 @@ impl ToChalk for AssocTyValue { } impl ToChalk for GenericPredicate { - type Chalk = chalk_ir::QuantifiedWhereClause; + type Chalk = chalk_ir::QuantifiedWhereClause; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { + fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { match self { GenericPredicate::Implemented(trait_ref) => { make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) @@ -259,7 +262,7 @@ impl ToChalk for GenericPredicate { fn from_chalk( db: &impl HirDatabase, - where_clause: chalk_ir::QuantifiedWhereClause, + where_clause: chalk_ir::QuantifiedWhereClause, ) -> GenericPredicate { match where_clause.value { chalk_ir::WhereClause::Implemented(tr) => { @@ -279,9 +282,9 @@ impl ToChalk for GenericPredicate { } impl ToChalk for ProjectionTy { - type Chalk = chalk_ir::ProjectionTy; + type Chalk = chalk_ir::ProjectionTy; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { + fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { chalk_ir::ProjectionTy { associated_ty_id: self.associated_ty.to_chalk(db), parameters: self.parameters.to_chalk(db), @@ -290,7 +293,7 @@ impl ToChalk for ProjectionTy { fn from_chalk( db: &impl HirDatabase, - projection_ty: chalk_ir::ProjectionTy, + projection_ty: chalk_ir::ProjectionTy, ) -> ProjectionTy { ProjectionTy { associated_ty: from_chalk(db, projection_ty.associated_ty_id), @@ -300,31 +303,31 @@ impl ToChalk for ProjectionTy { } impl ToChalk for super::ProjectionPredicate { - type Chalk = chalk_ir::Normalize; + type Chalk = chalk_ir::Normalize; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize { + fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize { chalk_ir::Normalize { projection: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db), } } - fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self { + fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self { unimplemented!() } } impl ToChalk for Obligation { - type Chalk = chalk_ir::DomainGoal; + type Chalk = chalk_ir::DomainGoal; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal { + fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal { match self { Obligation::Trait(tr) => tr.to_chalk(db).cast(), Obligation::Projection(pr) => pr.to_chalk(db).cast(), } } - fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { + fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { unimplemented!() } } @@ -348,16 +351,17 @@ where } impl ToChalk for Arc { - type Chalk = chalk_ir::Environment; + type Chalk = chalk_ir::Environment; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment { + fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment { let mut clauses = Vec::new(); for pred in &self.predicates { if pred.is_error() { // for env, we just ignore errors continue; } - let program_clause: chalk_ir::ProgramClause = pred.clone().to_chalk(db).cast(); + let program_clause: chalk_ir::ProgramClause = + pred.clone().to_chalk(db).cast(); clauses.push(program_clause.into_from_env_clause()); } chalk_ir::Environment::new().add_clauses(clauses) @@ -365,7 +369,7 @@ impl ToChalk for Arc { fn from_chalk( _db: &impl HirDatabase, - _env: chalk_ir::Environment, + _env: chalk_ir::Environment, ) -> Arc { unimplemented!() } @@ -373,7 +377,7 @@ impl ToChalk for Arc { impl ToChalk for super::InEnvironment where - T::Chalk: chalk_ir::family::HasTypeFamily, + T::Chalk: chalk_ir::family::HasTypeFamily, { type Chalk = chalk_ir::InEnvironment; @@ -396,9 +400,9 @@ where } impl ToChalk for builtin::BuiltinImplData { - type Chalk = chalk_rust_ir::ImplDatum; + type Chalk = ImplDatum; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::ImplDatum { + fn to_chalk(self, db: &impl HirDatabase) -> ImplDatum { let impl_type = chalk_rust_ir::ImplType::External; let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect(); @@ -414,15 +418,15 @@ impl ToChalk for builtin::BuiltinImplData { } } - fn from_chalk(_db: &impl HirDatabase, _data: chalk_rust_ir::ImplDatum) -> Self { + fn from_chalk(_db: &impl HirDatabase, _data: ImplDatum) -> Self { unimplemented!() } } impl ToChalk for builtin::BuiltinImplAssocTyValueData { - type Chalk = chalk_rust_ir::AssociatedTyValue; + type Chalk = AssociatedTyValue; - fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValue { + fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValue { let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) }; chalk_rust_ir::AssociatedTyValue { @@ -434,7 +438,7 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData { fn from_chalk( _db: &impl HirDatabase, - _data: chalk_rust_ir::AssociatedTyValue, + _data: AssociatedTyValue, ) -> builtin::BuiltinImplAssocTyValueData { unimplemented!() } @@ -451,7 +455,7 @@ fn convert_where_clauses( db: &impl HirDatabase, def: GenericDefId, substs: &Substs, -) -> Vec> { +) -> Vec> { let generic_predicates = db.generic_predicates(def); let mut result = Vec::with_capacity(generic_predicates.len()); for pred in generic_predicates.iter() { @@ -465,7 +469,7 @@ fn convert_where_clauses( result } -impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> +impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB> where DB: HirDatabase, { @@ -516,7 +520,7 @@ where fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc { self.db.associated_ty_value(self.krate.into(), id) } - fn custom_clauses(&self) -> Vec> { + fn custom_clauses(&self) -> Vec> { vec![] } fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec { @@ -613,7 +617,7 @@ pub(crate) fn struct_datum_query( struct_id: StructId, ) -> Arc { debug!("struct_datum {:?}", struct_id); - let type_ctor: TypeCtor = from_chalk(db, struct_id); + let type_ctor: TypeCtor = from_chalk(db, TypeName::Struct(struct_id)); debug!("struct {:?} = {:?}", struct_id, type_ctor); let num_params = type_ctor.num_ty_params(db); let upstream = type_ctor.krate(db) != Some(krate); @@ -733,8 +737,8 @@ fn invalid_impl_datum() -> Arc { pub(crate) fn associated_ty_value_query( db: &impl HirDatabase, krate: CrateId, - id: chalk_rust_ir::AssociatedTyValueId, -) -> Arc> { + id: AssociatedTyValueId, +) -> Arc { let data: AssocTyValue = from_chalk(db, id); match data { AssocTyValue::TypeAlias(type_alias) => { -- cgit v1.2.3 From 4053fcfca0e33f133c53fa755c1b1bcc0b4c11bb Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 21 Dec 2019 15:00:44 +0100 Subject: Introduce our own Chalk TypeFamily, instead of using ChalkIr It's not very different, except we can directly use Salsa IDs instead of casting them. This means we need to refactor the handling of errors to get rid of UNKNOWN_TRAIT though. --- crates/ra_hir_ty/src/tests/method_resolution.rs | 4 +- crates/ra_hir_ty/src/traits.rs | 4 +- crates/ra_hir_ty/src/traits/builtin.rs | 49 +++++--- crates/ra_hir_ty/src/traits/chalk.rs | 156 ++++++++++++++---------- 4 files changed, 126 insertions(+), 87 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 45164c9e9..ce9a06fde 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -865,7 +865,7 @@ mod foo { #[test] fn method_resolution_where_clause_for_unknown_trait() { - // The blanket impl shouldn't apply because we can't even resolve UnknownTrait + // The blanket impl currently applies because we ignore the unresolved where clause let t = type_at( r#" //- /main.rs @@ -875,7 +875,7 @@ impl Trait for T where T: UnknownTrait {} fn test() { (&S).foo()<|>; } "#, ); - assert_eq!(t, "{unknown}"); + assert_eq!(t, "u128"); } #[test] diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index fbab60925..c4dc857bc 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs @@ -291,7 +291,7 @@ impl FnTrait { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ClosureFnTraitImplData { def: DefWithBodyId, expr: ExprId, @@ -300,7 +300,7 @@ pub struct ClosureFnTraitImplData { /// An impl. Usually this comes from an impl block, but some built-in types get /// synthetic impls. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Impl { /// A normal impl from an impl block. ImplBlock(ImplId), diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs index cd587a338..dd41176f0 100644 --- a/crates/ra_hir_ty/src/traits/builtin.rs +++ b/crates/ra_hir_ty/src/traits/builtin.rs @@ -28,24 +28,24 @@ pub(super) fn get_builtin_impls( trait_: TraitId, mut callback: impl FnMut(Impl), ) { + // Note: since impl_datum needs to be infallible, we need to make sure here + // that we have all prerequisites to build the respective impls. if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() { if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) { if trait_ == actual_trait { let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; - callback(Impl::ClosureFnTraitImpl(impl_)); + if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) { + callback(Impl::ClosureFnTraitImpl(impl_)); + } } } } } } -pub(super) fn impl_datum( - db: &impl HirDatabase, - krate: CrateId, - impl_: Impl, -) -> Option { +pub(super) fn impl_datum(db: &impl HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData { match impl_ { Impl::ImplBlock(_) => unreachable!(), Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), @@ -65,21 +65,38 @@ pub(super) fn associated_ty_value( } } +fn check_closure_fn_trait_impl_prerequisites( + db: &impl HirDatabase, + krate: CrateId, + data: super::ClosureFnTraitImplData, +) -> bool { + // the respective Fn/FnOnce/FnMut trait needs to exist + if get_fn_trait(db, krate, data.fn_trait).is_none() { + return false; + } + + // FIXME: there are more assumptions that we should probably check here: + // the traits having no type params, FnOnce being a supertrait + + // the FnOnce trait needs to exist and have an assoc type named Output + let fn_once_trait = match get_fn_trait(db, krate, super::FnTrait::FnOnce) { + Some(t) => t, + None => return false, + }; + db.trait_data(fn_once_trait).associated_type_by_name(&name![Output]).is_some() +} + fn closure_fn_trait_impl_datum( db: &impl HirDatabase, krate: CrateId, data: super::ClosureFnTraitImplData, -) -> Option { +) -> BuiltinImplData { // for some closure |X, Y| -> Z: // impl Fn<(T, U)> for closure V> { Output = V } - let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait - - // validate FnOnce trait, since we need it in the assoc ty value definition - // and don't want to return a valid value only to find out later that FnOnce - // is broken - let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; - let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; + let trait_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait + // the existence of the Fn trait has been checked before + .expect("fn trait for closure impl missing"); let num_args: u16 = match &db.body(data.def.into())[data.expr] { Expr::Lambda { args, .. } => args.len() as u16, @@ -107,12 +124,12 @@ fn closure_fn_trait_impl_datum( let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()); - Some(BuiltinImplData { + BuiltinImplData { num_vars: num_args as usize + 1, trait_ref, where_clauses: Vec::new(), assoc_ty_values: vec![output_ty_id], - }) + } } fn closure_fn_trait_output_assoc_ty_value( diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index d53d3fdeb..9e38337e5 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -1,5 +1,5 @@ //! Conversion code from/to Chalk. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use log::debug; @@ -17,7 +17,73 @@ use crate::{ ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, }; -pub type TypeFamily = chalk_ir::family::ChalkIr; +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct TypeFamily {} + +impl chalk_ir::family::TypeFamily for TypeFamily { + type InternedType = Box>; + type InternedLifetime = chalk_ir::LifetimeData; + type InternedParameter = chalk_ir::ParameterData; + type DefId = InternId; + + // FIXME: implement these + fn debug_struct_id( + _type_kind_id: chalk_ir::StructId, + _fmt: &mut fmt::Formatter<'_>, + ) -> Option { + None + } + + fn debug_trait_id( + _type_kind_id: chalk_ir::TraitId, + _fmt: &mut fmt::Formatter<'_>, + ) -> Option { + None + } + + fn debug_assoc_type_id( + _id: chalk_ir::AssocTypeId, + _fmt: &mut fmt::Formatter<'_>, + ) -> Option { + None + } + + fn debug_projection( + _projection: &chalk_ir::ProjectionTy, + _fmt: &mut fmt::Formatter<'_>, + ) -> Option { + None + } + + fn intern_ty(ty: chalk_ir::TyData) -> Box> { + Box::new(ty) + } + + fn ty_data(ty: &Box>) -> &chalk_ir::TyData { + ty + } + + fn intern_lifetime(lifetime: chalk_ir::LifetimeData) -> chalk_ir::LifetimeData { + lifetime + } + + fn lifetime_data(lifetime: &chalk_ir::LifetimeData) -> &chalk_ir::LifetimeData { + lifetime + } + + fn intern_parameter(parameter: chalk_ir::ParameterData) -> chalk_ir::ParameterData { + parameter + } + + fn parameter_data(parameter: &chalk_ir::ParameterData) -> &chalk_ir::ParameterData { + parameter + } +} + +impl chalk_ir::family::HasTypeFamily for TypeFamily { + type TypeFamily = Self; +} + pub type AssocTypeId = chalk_ir::AssocTypeId; pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum; pub type TraitId = chalk_ir::TraitId; @@ -29,9 +95,6 @@ pub type ImplDatum = chalk_rust_ir::ImplDatum; pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue; -/// This represents a trait whose name we could not resolve. -const UNKNOWN_TRAIT: TraitId = chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); - pub(super) trait ToChalk { type Chalk; fn to_chalk(self, db: &impl HirDatabase) -> Self::Chalk; @@ -162,11 +225,11 @@ impl ToChalk for hir_def::TraitId { type Chalk = TraitId; fn to_chalk(self, _db: &impl HirDatabase) -> TraitId { - chalk_ir::TraitId(id_to_chalk(self)) + chalk_ir::TraitId(self.as_intern_id()) } fn from_chalk(_db: &impl HirDatabase, trait_id: TraitId) -> hir_def::TraitId { - id_from_chalk(trait_id.0) + InternKey::from_intern_id(trait_id.0) } } @@ -215,11 +278,11 @@ impl ToChalk for TypeAliasId { type Chalk = AssocTypeId; fn to_chalk(self, _db: &impl HirDatabase) -> AssocTypeId { - chalk_ir::AssocTypeId(id_to_chalk(self)) + chalk_ir::AssocTypeId(self.as_intern_id()) } fn from_chalk(_db: &impl HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId { - id_from_chalk(type_alias_id.0) + InternKey::from_intern_id(type_alias_id.0) } } @@ -250,13 +313,7 @@ impl ToChalk for GenericPredicate { }), 0, ), - GenericPredicate::Error => { - let impossible_trait_ref = chalk_ir::TraitRef { - trait_id: UNKNOWN_TRAIT, - parameters: vec![Ty::Unknown.to_chalk(db).cast()], - }; - make_binders(chalk_ir::WhereClause::Implemented(impossible_trait_ref), 0) - } + GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), } } @@ -266,10 +323,6 @@ impl ToChalk for GenericPredicate { ) -> GenericPredicate { match where_clause.value { chalk_ir::WhereClause::Implemented(tr) => { - if tr.trait_id == UNKNOWN_TRAIT { - // FIXME we need an Error enum on the Chalk side to avoid this - return GenericPredicate::Error; - } GenericPredicate::Implemented(from_chalk(db, tr)) } chalk_ir::WhereClause::ProjectionEq(projection_eq) => { @@ -460,9 +513,8 @@ fn convert_where_clauses( let mut result = Vec::with_capacity(generic_predicates.len()); for pred in generic_predicates.iter() { if pred.is_error() { - // HACK: Return just the single predicate (which is always false - // anyway), otherwise Chalk can easily get into slow situations - return vec![pred.clone().subst(substs).to_chalk(db)]; + // skip errored predicates completely + continue; } result.push(pred.clone().subst(substs).to_chalk(db)); } @@ -491,10 +543,11 @@ where parameters: &[Parameter], ) -> Vec { debug!("impls_for_trait {:?}", trait_id); - if trait_id == UNKNOWN_TRAIT { - return Vec::new(); - } let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); + + // Note: Since we're using impls_for_trait, only impls where the trait + // can be resolved should ever reach Chalk. `impl_datum` relies on that + // and will panic if the trait can't be resolved. let mut result: Vec<_> = self .db .impls_for_trait(self.krate, trait_.into()) @@ -566,24 +619,6 @@ pub(crate) fn trait_datum_query( trait_id: TraitId, ) -> Arc { debug!("trait_datum {:?}", trait_id); - if trait_id == UNKNOWN_TRAIT { - let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses: Vec::new() }; - - let flags = chalk_rust_ir::TraitFlags { - auto: false, - marker: false, - upstream: true, - fundamental: false, - non_enumerable: true, - coinductive: false, - }; - return Arc::new(TraitDatum { - id: trait_id, - binders: make_binders(trait_datum_bound, 1), - flags, - associated_ty_ids: vec![], - }); - } let trait_: hir_def::TraitId = from_chalk(db, trait_id); let trait_data = db.trait_data(trait_); debug!("trait {:?} = {:?}", trait_id, trait_data.name); @@ -653,9 +688,8 @@ pub(crate) fn impl_datum_query( let impl_: Impl = from_chalk(db, impl_id); match impl_ { Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block), - _ => builtin::impl_datum(db, krate, impl_).map(|d| Arc::new(d.to_chalk(db))), + _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)), } - .unwrap_or_else(invalid_impl_datum) } fn impl_block_datum( @@ -663,8 +697,11 @@ fn impl_block_datum( krate: CrateId, chalk_id: ImplId, impl_id: hir_def::ImplId, -) -> Option> { - let trait_ref = db.impl_trait(impl_id)?; +) -> Arc { + let trait_ref = db + .impl_trait(impl_id) + // ImplIds for impls where the trait ref can't be resolved should never reach Chalk + .expect("invalid impl passed to Chalk"); let impl_data = db.impl_data(impl_id); let generic_params = generics(db, impl_id.into()); @@ -716,21 +753,6 @@ fn impl_block_datum( polarity, associated_ty_value_ids, }; - Some(Arc::new(impl_datum)) -} - -fn invalid_impl_datum() -> Arc { - let trait_ref = chalk_ir::TraitRef { - trait_id: UNKNOWN_TRAIT, - parameters: vec![chalk_ir::TyData::BoundVar(0).cast().intern().cast()], - }; - let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses: Vec::new() }; - let impl_datum = ImplDatum { - binders: make_binders(impl_datum_bound, 1), - impl_type: chalk_rust_ir::ImplType::External, - polarity: chalk_rust_ir::Polarity::Positive, - associated_ty_value_ids: Vec::new(), - }; Arc::new(impl_datum) } @@ -786,25 +808,25 @@ fn id_to_chalk(salsa_id: T) -> chalk_ir::RawId { impl From for crate::TypeCtorId { fn from(struct_id: StructId) -> Self { - id_from_chalk(struct_id.0) + InternKey::from_intern_id(struct_id.0) } } impl From for StructId { fn from(type_ctor_id: crate::TypeCtorId) -> Self { - chalk_ir::StructId(id_to_chalk(type_ctor_id)) + chalk_ir::StructId(type_ctor_id.as_intern_id()) } } impl From for crate::traits::GlobalImplId { fn from(impl_id: ImplId) -> Self { - id_from_chalk(impl_id.0) + InternKey::from_intern_id(impl_id.0) } } impl From for ImplId { fn from(impl_id: crate::traits::GlobalImplId) -> Self { - chalk_ir::ImplId(id_to_chalk(impl_id)) + chalk_ir::ImplId(impl_id.as_intern_id()) } } -- cgit v1.2.3 From 1f7f4578f72721c1b0e17e8405f986fd2ce89aaf Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 21 Dec 2019 19:15:06 +0100 Subject: Filter out error predicates in type bounds as well --- crates/ra_hir_ty/src/tests/traits.rs | 17 +++++++++++++++++ crates/ra_hir_ty/src/traits/chalk.rs | 14 ++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 76e2198b6..ae316922b 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -958,6 +958,23 @@ fn test() { ); } +#[test] +fn error_bound_chalk() { + let t = type_at( + r#" +//- /main.rs +trait Trait { + fn foo(&self) -> u32 {} +} + +fn test(x: (impl Trait + UnknownTrait)) { + x.foo()<|>; +} +"#, + ); + assert_eq!(t, "u32"); +} + #[test] fn assoc_type_bindings() { assert_snapshot!( diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 9e38337e5..555930c9b 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -129,12 +129,22 @@ impl ToChalk for Ty { Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), Ty::Dyn(predicates) => { - let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); + let where_clauses = predicates + .iter() + .filter(|p| !p.is_error()) + .cloned() + .map(|p| p.to_chalk(db)) + .collect(); let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) }; chalk_ir::TyData::Dyn(bounded_ty).intern() } Ty::Opaque(predicates) => { - let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); + let where_clauses = predicates + .iter() + .filter(|p| !p.is_error()) + .cloned() + .map(|p| p.to_chalk(db)) + .collect(); let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) }; chalk_ir::TyData::Opaque(bounded_ty).intern() } -- cgit v1.2.3