aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_ty/src/db.rs5
-rw-r--r--crates/ra_hir_ty/src/lib.rs6
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs74
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs39
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/interner.rs2
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs53
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs18
7 files changed, 179 insertions, 18 deletions
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index dfc6c7dd6..0a8bb24ac 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -76,6 +76,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
76 #[salsa::interned] 76 #[salsa::interned]
77 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; 77 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId;
78 #[salsa::interned] 78 #[salsa::interned]
79 fn intern_callable_def(&self, callable_def: CallableDef) -> crate::CallableDefId;
80 #[salsa::interned]
79 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; 81 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
80 #[salsa::interned] 82 #[salsa::interned]
81 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; 83 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId;
@@ -94,6 +96,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
94 #[salsa::invoke(crate::traits::chalk::impl_datum_query)] 96 #[salsa::invoke(crate::traits::chalk::impl_datum_query)]
95 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; 97 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
96 98
99 #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)]
100 fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc<chalk::FnDefDatum>;
101
97 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] 102 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)]
98 fn associated_ty_value( 103 fn associated_ty_value(
99 &self, 104 &self,
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index e91c9be04..93cb45a64 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -159,6 +159,12 @@ pub enum TypeCtor {
159pub struct TypeCtorId(salsa::InternId); 159pub struct TypeCtorId(salsa::InternId);
160impl_intern_key!(TypeCtorId); 160impl_intern_key!(TypeCtorId);
161 161
162/// This exists just for Chalk, because Chalk just has a single `FnDefId` where
163/// we have different IDs for struct and enum variant constructors.
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
165pub struct CallableDefId(salsa::InternId);
166impl_intern_key!(CallableDefId);
167
162impl TypeCtor { 168impl TypeCtor {
163 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { 169 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
164 match self { 170 match self {
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 6826610cb..0419bc751 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -2644,6 +2644,80 @@ fn test() {
2644} 2644}
2645 2645
2646#[test] 2646#[test]
2647fn builtin_fn_def_copy() {
2648 assert_snapshot!(
2649 infer_with_mismatches(r#"
2650#[lang = "copy"]
2651trait Copy {}
2652
2653fn foo() {}
2654fn bar<T: Copy>(T) -> T {}
2655struct Struct(usize);
2656enum Enum { Variant(usize) }
2657
2658trait Test { fn test(&self) -> bool; }
2659impl<T: Copy> Test for T {}
2660
2661fn test() {
2662 foo.test();
2663 bar.test();
2664 Struct.test();
2665 Enum::Variant.test();
2666}
2667"#, true),
2668 // wrong result, because the built-in Copy impl for fn defs doesn't exist in Chalk yet
2669 @r###"
2670 42..44 '{}': ()
2671 61..62 'T': {unknown}
2672 69..71 '{}': ()
2673 69..71: expected T, got ()
2674 146..150 'self': &Self
2675 202..282 '{ ...t(); }': ()
2676 208..211 'foo': fn foo()
2677 208..218 'foo.test()': {unknown}
2678 224..227 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2679 224..234 'bar.test()': {unknown}
2680 240..246 'Struct': Struct(usize) -> Struct
2681 240..253 'Struct.test()': {unknown}
2682 259..272 'Enum::Variant': Variant(usize) -> Enum
2683 259..279 'Enum::...test()': {unknown}
2684 "###
2685 );
2686}
2687
2688#[test]
2689fn builtin_fn_ptr_copy() {
2690 assert_snapshot!(
2691 infer_with_mismatches(r#"
2692#[lang = "copy"]
2693trait Copy {}
2694
2695trait Test { fn test(&self) -> bool; }
2696impl<T: Copy> Test for T {}
2697
2698fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2699 f1.test();
2700 f2.test();
2701 f3.test();
2702}
2703"#, true),
2704 @r###"
2705 55..59 'self': &Self
2706 109..111 'f1': fn()
2707 119..121 'f2': fn(usize) -> u8
2708 140..142 'f3': fn(u8, u8) -> &u8
2709 163..211 '{ ...t(); }': ()
2710 169..171 'f1': fn()
2711 169..178 'f1.test()': bool
2712 184..186 'f2': fn(usize) -> u8
2713 184..193 'f2.test()': bool
2714 199..201 'f3': fn(u8, u8) -> &u8
2715 199..208 'f3.test()': bool
2716 "###
2717 );
2718}
2719
2720#[test]
2647fn builtin_sized() { 2721fn builtin_sized() {
2648 assert_snapshot!( 2722 assert_snapshot!(
2649 infer_with_mismatches(r#" 2723 infer_with_mismatches(r#"
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index e2f2a9ccb..5b0f12a3c 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -14,7 +14,7 @@ use ra_db::{salsa::InternKey, CrateId};
14use super::{builtin, AssocTyValue, ChalkContext, Impl}; 14use super::{builtin, AssocTyValue, ChalkContext, Impl};
15use crate::{ 15use crate::{
16 db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics, 16 db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics,
17 DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, 17 CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor,
18}; 18};
19use chalk_rust_ir::WellKnownTrait; 19use chalk_rust_ir::WellKnownTrait;
20use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; 20use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
@@ -54,10 +54,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
54 54
55 fn fn_def_datum( 55 fn fn_def_datum(
56 &self, 56 &self,
57 _fn_def_id: chalk_ir::FnDefId<Interner>, 57 fn_def_id: chalk_ir::FnDefId<Interner>,
58 ) -> Arc<chalk_rust_ir::FnDefDatum<Interner>> { 58 ) -> Arc<chalk_rust_ir::FnDefDatum<Interner>> {
59 // We don't yet provide any FnDefs to Chalk 59 self.db.fn_def_datum(self.krate, fn_def_id)
60 unimplemented!()
61 } 60 }
62 61
63 fn impls_for_trait( 62 fn impls_for_trait(
@@ -405,6 +404,26 @@ fn type_alias_associated_ty_value(
405 Arc::new(value) 404 Arc::new(value)
406} 405}
407 406
407pub(crate) fn fn_def_datum_query(
408 db: &dyn HirDatabase,
409 _krate: CrateId,
410 fn_def_id: FnDefId,
411) -> Arc<FnDefDatum> {
412 let callable_def: CallableDef = from_chalk(db, fn_def_id);
413 let generic_params = generics(db.upcast(), callable_def.into());
414 let sig = db.callable_item_signature(callable_def);
415 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
416 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
417 let bound = chalk_rust_ir::FnDefDatumBound {
418 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
419 argument_types: sig.value.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(),
420 return_type: sig.value.ret().clone().to_chalk(db),
421 where_clauses,
422 };
423 let datum = FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders) };
424 Arc::new(datum)
425}
426
408impl From<AdtId> for crate::TypeCtorId { 427impl From<AdtId> for crate::TypeCtorId {
409 fn from(struct_id: AdtId) -> Self { 428 fn from(struct_id: AdtId) -> Self {
410 struct_id.0 429 struct_id.0
@@ -417,6 +436,18 @@ impl From<crate::TypeCtorId> for AdtId {
417 } 436 }
418} 437}
419 438
439impl From<FnDefId> for crate::CallableDefId {
440 fn from(fn_def_id: FnDefId) -> Self {
441 InternKey::from_intern_id(fn_def_id.0)
442 }
443}
444
445impl From<crate::CallableDefId> for FnDefId {
446 fn from(callable_def_id: crate::CallableDefId) -> Self {
447 chalk_ir::FnDefId(callable_def_id.as_intern_id())
448 }
449}
450
420impl From<ImplId> for crate::traits::GlobalImplId { 451impl From<ImplId> for crate::traits::GlobalImplId {
421 fn from(impl_id: ImplId) -> Self { 452 fn from(impl_id: ImplId) -> Self {
422 InternKey::from_intern_id(impl_id.0) 453 InternKey::from_intern_id(impl_id.0)
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<Interner>;
20pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>; 20pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>;
21pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>; 21pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>;
22pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>; 22pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>;
23pub type FnDefId = chalk_ir::FnDefId<Interner>;
24pub type FnDefDatum = chalk_rust_ir::FnDefDatum<Interner>;
23 25
24impl chalk_ir::interner::Interner for Interner { 26impl chalk_ir::interner::Interner for Interner {
25 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc? 27 type InternedType = Box<chalk_ir::TyData<Self>>; // 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..7082cb095 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::{
15 db::HirDatabase, 15 db::HirDatabase,
16 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, 16 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain},
17 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 17 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation},
18 ApplicationTy, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, Substs, 18 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy,
19 TraitEnvironment, TraitRef, Ty, TypeCtor, 19 Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
20}; 20};
21 21
22use super::interner::*; 22use super::interner::*;
@@ -26,14 +26,19 @@ impl ToChalk for Ty {
26 type Chalk = chalk_ir::Ty<Interner>; 26 type Chalk = chalk_ir::Ty<Interner>;
27 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 27 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
28 match self { 28 match self {
29 Ty::Apply(apply_ty) => { 29 Ty::Apply(apply_ty) => match apply_ty.ctor {
30 if let TypeCtor::Ref(m) = apply_ty.ctor { 30 TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters),
31 return ref_to_chalk(db, m, apply_ty.parameters); 31 TypeCtor::FnPtr { num_args: _ } => {
32 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
33 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
34 .intern(&Interner)
32 } 35 }
33 let name = apply_ty.ctor.to_chalk(db); 36 _ => {
34 let substitution = apply_ty.parameters.to_chalk(db); 37 let name = apply_ty.ctor.to_chalk(db);
35 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 38 let substitution = apply_ty.parameters.to_chalk(db);
36 } 39 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
40 }
41 },
37 Ty::Projection(proj_ty) => { 42 Ty::Projection(proj_ty) => {
38 let associated_ty_id = proj_ty.associated_ty.to_chalk(db); 43 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
39 let substitution = proj_ty.parameters.to_chalk(db); 44 let substitution = proj_ty.parameters.to_chalk(db);
@@ -93,7 +98,13 @@ impl ToChalk for Ty {
93 Ty::Projection(ProjectionTy { associated_ty, parameters }) 98 Ty::Projection(ProjectionTy { associated_ty, parameters })
94 } 99 }
95 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), 100 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(),
96 chalk_ir::TyData::Function(_) => unimplemented!(), 101 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => {
102 let parameters: Substs = from_chalk(db, substitution);
103 Ty::Apply(ApplicationTy {
104 ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 },
105 parameters,
106 })
107 }
97 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), 108 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
98 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 109 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
99 chalk_ir::TyData::Dyn(where_clauses) => { 110 chalk_ir::TyData::Dyn(where_clauses) => {
@@ -217,11 +228,14 @@ impl ToChalk for TypeCtor {
217 TypeCtor::Slice => TypeName::Slice, 228 TypeCtor::Slice => TypeName::Slice,
218 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), 229 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
219 TypeCtor::Str => TypeName::Str, 230 TypeCtor::Str => TypeName::Str,
231 TypeCtor::FnDef(callable_def) => {
232 let id = callable_def.to_chalk(db);
233 TypeName::FnDef(id)
234 }
220 TypeCtor::Int(Uncertain::Unknown) 235 TypeCtor::Int(Uncertain::Unknown)
221 | TypeCtor::Float(Uncertain::Unknown) 236 | TypeCtor::Float(Uncertain::Unknown)
222 | TypeCtor::Adt(_) 237 | TypeCtor::Adt(_)
223 | TypeCtor::Array 238 | TypeCtor::Array
224 | TypeCtor::FnDef(_)
225 | TypeCtor::FnPtr { .. } 239 | TypeCtor::FnPtr { .. }
226 | TypeCtor::Never 240 | TypeCtor::Never
227 | TypeCtor::Closure { .. } => { 241 | TypeCtor::Closure { .. } => {
@@ -260,7 +274,10 @@ impl ToChalk for TypeCtor {
260 TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)), 274 TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
261 TypeName::Str => TypeCtor::Str, 275 TypeName::Str => TypeCtor::Str,
262 276
263 TypeName::FnDef(_) => unreachable!(), 277 TypeName::FnDef(fn_def_id) => {
278 let callable_def = from_chalk(db, fn_def_id);
279 TypeCtor::FnDef(callable_def)
280 }
264 281
265 TypeName::Error => { 282 TypeName::Error => {
266 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 283 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
@@ -347,6 +364,18 @@ impl ToChalk for Impl {
347 } 364 }
348} 365}
349 366
367impl ToChalk for CallableDef {
368 type Chalk = FnDefId;
369
370 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
371 db.intern_callable_def(self).into()
372 }
373
374 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef {
375 db.lookup_intern_callable_def(fn_def_id.into())
376 }
377}
378
350impl ToChalk for TypeAliasId { 379impl ToChalk for TypeAliasId {
351 type Chalk = AssocTypeId; 380 type Chalk = AssocTypeId;
352 381
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<'_> {
247 247
248 pub fn debug_fn_def_id( 248 pub fn debug_fn_def_id(
249 &self, 249 &self,
250 _fn_def_id: chalk_ir::FnDefId<Interner>, 250 fn_def_id: chalk_ir::FnDefId<Interner>,
251 fmt: &mut fmt::Formatter<'_>, 251 fmt: &mut fmt::Formatter<'_>,
252 ) -> Result<(), fmt::Error> { 252 ) -> Result<(), fmt::Error> {
253 write!(fmt, "fn") 253 let def: CallableDef = from_chalk(self.0, fn_def_id);
254 let name = match def {
255 CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(),
256 CallableDef::StructId(s) => self.0.struct_data(s).name.clone(),
257 CallableDef::EnumVariantId(e) => {
258 let enum_data = self.0.enum_data(e.parent);
259 enum_data.variants[e.local_id].name.clone()
260 }
261 };
262 match def {
263 CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name),
264 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {
265 write!(fmt, "{{ctor {}}}", name)
266 }
267 }
254 } 268 }
255 269
256 pub fn debug_const( 270 pub fn debug_const(