aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorMikhail Rakhmanov <[email protected]>2020-06-13 07:42:15 +0100
committerMikhail Rakhmanov <[email protected]>2020-06-13 07:42:15 +0100
commit16bbf4ab7f132e6e5e5318dccdef9a5d71afdd7f (patch)
tree4b79fa8c046be56b02427ba843e70cdf3ac05767 /crates/ra_hir_ty
parenteeb8b9e236796da8734ba81a49164864497f7226 (diff)
parentb56ad148db0c69eb279c225f45d324b4e80e7367 (diff)
Merge branch 'master' into keyword_completion
# Conflicts: # docs/user/generated_features.adoc
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/Cargo.toml4
-rw-r--r--crates/ra_hir_ty/src/db.rs20
-rw-r--r--crates/ra_hir_ty/src/display.rs39
-rw-r--r--crates/ra_hir_ty/src/expr.rs10
-rw-r--r--crates/ra_hir_ty/src/infer.rs52
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs28
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs3
-rw-r--r--crates/ra_hir_ty/src/lib.rs104
-rw-r--r--crates/ra_hir_ty/src/lower.rs214
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs12
-rw-r--r--crates/ra_hir_ty/src/primitive.rs54
-rw-r--r--crates/ra_hir_ty/src/test_db.rs22
-rw-r--r--crates/ra_hir_ty/src/tests/display_source_code.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs54
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs112
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs174
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs52
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/interner.rs2
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs74
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs5
20 files changed, 701 insertions, 338 deletions
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 4b8dcdc07..112fcd07e 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -27,8 +27,8 @@ test_utils = { path = "../test_utils" }
27 27
28scoped-tls = "1" 28scoped-tls = "1"
29 29
30chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "329b7f3fdd2431ed6f6778cde53f22374c7d094c" } 30chalk-solve = "0.11"
31chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "329b7f3fdd2431ed6f6778cde53f22374c7d094c" } 31chalk-ir = "0.11"
32 32
33[dev-dependencies] 33[dev-dependencies]
34insta = "0.16.0" 34insta = "0.16.0"
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 0a8bb24ac..bf71d38d6 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -3,8 +3,8 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{ 5use hir_def::{
6 db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalFieldId, TraitId, TypeParamId, 6 db::DefDatabase, DefWithBodyId, FunctionId, GenericDefId, ImplId, LocalFieldId, TraitId,
7 VariantId, 7 TypeParamId, VariantId,
8}; 8};
9use ra_arena::map::ArenaMap; 9use ra_arena::map::ArenaMap;
10use ra_db::{impl_intern_key, salsa, CrateId, Upcast}; 10use ra_db::{impl_intern_key, salsa, CrateId, Upcast};
@@ -13,8 +13,8 @@ use ra_prof::profile;
13use crate::{ 13use crate::{
14 method_resolution::{CrateImplDefs, TyFingerprint}, 14 method_resolution::{CrateImplDefs, TyFingerprint},
15 traits::{chalk, AssocTyValue, Impl}, 15 traits::{chalk, AssocTyValue, Impl},
16 Binders, CallableDef, GenericPredicate, InferenceResult, PolyFnSig, Substs, TraitRef, Ty, 16 Binders, CallableDef, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig,
17 TyDefId, TypeCtor, ValueTyDefId, 17 ReturnTypeImplTraits, Substs, TraitRef, Ty, TyDefId, TypeCtor, ValueTyDefId,
18}; 18};
19use hir_expand::name::Name; 19use hir_expand::name::Name;
20 20
@@ -48,6 +48,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
48 #[salsa::invoke(crate::callable_item_sig)] 48 #[salsa::invoke(crate::callable_item_sig)]
49 fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig; 49 fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig;
50 50
51 #[salsa::invoke(crate::lower::return_type_impl_traits)]
52 fn return_type_impl_traits(
53 &self,
54 def: FunctionId,
55 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>>;
56
51 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 57 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
52 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 58 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
53 fn generic_predicates_for_param( 59 fn generic_predicates_for_param(
@@ -80,6 +86,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
80 #[salsa::interned] 86 #[salsa::interned]
81 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; 87 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
82 #[salsa::interned] 88 #[salsa::interned]
89 fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId;
90 #[salsa::interned]
83 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; 91 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId;
84 #[salsa::interned] 92 #[salsa::interned]
85 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; 93 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
@@ -142,3 +150,7 @@ fn hir_database_is_object_safe() {
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
143pub struct GlobalTypeParamId(salsa::InternId); 151pub struct GlobalTypeParamId(salsa::InternId);
144impl_intern_key!(GlobalTypeParamId); 152impl_intern_key!(GlobalTypeParamId);
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155pub struct InternedOpaqueTyId(salsa::InternId);
156impl_intern_key!(InternedOpaqueTyId);
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs
index b9c4d2e89..3c97e1354 100644
--- a/crates/ra_hir_ty/src/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
@@ -4,7 +4,7 @@ use std::fmt;
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, utils::generics, ApplicationTy, CallableDef, FnSig, GenericPredicate, 6 db::HirDatabase, utils::generics, ApplicationTy, CallableDef, FnSig, GenericPredicate,
7 Obligation, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 7 Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
8}; 8};
9use hir_def::{ 9use hir_def::{
10 find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId, 10 find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId,
@@ -359,6 +359,21 @@ impl HirDisplay for ApplicationTy {
359 write!(f, ">")?; 359 write!(f, ">")?;
360 } 360 }
361 } 361 }
362 TypeCtor::OpaqueType(opaque_ty_id) => {
363 let bounds = match opaque_ty_id {
364 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
365 let datas =
366 f.db.return_type_impl_traits(func).expect("impl trait id without data");
367 let data = (*datas)
368 .as_ref()
369 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
370 data.clone().subst(&self.parameters)
371 }
372 };
373 write!(f, "impl ")?;
374 write_bounds_like_dyn_trait(&bounds.value, f)?;
375 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
376 }
362 TypeCtor::Closure { .. } => { 377 TypeCtor::Closure { .. } => {
363 let sig = self.parameters[0].callable_sig(f.db); 378 let sig = self.parameters[0].callable_sig(f.db);
364 if let Some(sig) = sig { 379 if let Some(sig) = sig {
@@ -427,14 +442,24 @@ impl HirDisplay for Ty {
427 } 442 }
428 } 443 }
429 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 444 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
430 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 445 Ty::Dyn(predicates) => {
431 match self { 446 write!(f, "dyn ")?;
432 Ty::Dyn(_) => write!(f, "dyn ")?,
433 Ty::Opaque(_) => write!(f, "impl ")?,
434 _ => unreachable!(),
435 };
436 write_bounds_like_dyn_trait(predicates, f)?; 447 write_bounds_like_dyn_trait(predicates, f)?;
437 } 448 }
449 Ty::Opaque(opaque_ty) => {
450 let bounds = match opaque_ty.opaque_ty_id {
451 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
452 let datas =
453 f.db.return_type_impl_traits(func).expect("impl trait id without data");
454 let data = (*datas)
455 .as_ref()
456 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
457 data.clone().subst(&opaque_ty.parameters)
458 }
459 };
460 write!(f, "impl ")?;
461 write_bounds_like_dyn_trait(&bounds.value, f)?;
462 }
438 Ty::Unknown => write!(f, "{{unknown}}")?, 463 Ty::Unknown => write!(f, "{{unknown}}")?,
439 Ty::Infer(..) => write!(f, "_")?, 464 Ty::Infer(..) => write!(f, "_")?,
440 } 465 }
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index f04968e14..7db928dde 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -226,17 +226,19 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
226 None => return, 226 None => return,
227 }; 227 };
228 228
229 let std_result_path = path![std::result::Result]; 229 let core_result_path = path![core::result::Result];
230 230
231 let resolver = self.func.resolver(db.upcast()); 231 let resolver = self.func.resolver(db.upcast());
232 let std_result_enum = match resolver.resolve_known_enum(db.upcast(), &std_result_path) { 232 let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) {
233 Some(it) => it, 233 Some(it) => it,
234 _ => return, 234 _ => return,
235 }; 235 };
236 236
237 let std_result_ctor = TypeCtor::Adt(AdtId::EnumId(std_result_enum)); 237 let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum));
238 let params = match &mismatch.expected { 238 let params = match &mismatch.expected {
239 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, 239 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => {
240 parameters
241 }
240 _ => return, 242 _ => return,
241 }; 243 };
242 244
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index dc77e88e5..3719f76a6 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -39,8 +39,7 @@ use ra_syntax::SmolStr;
39use super::{ 39use super::{
40 primitive::{FloatTy, IntTy}, 40 primitive::{FloatTy, IntTy},
41 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 41 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
42 ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment, 42 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
43 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain,
44}; 43};
45use crate::{ 44use crate::{
46 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 45 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
@@ -312,12 +311,6 @@ impl<'a> InferenceContext<'a> {
312 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 311 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
313 match ty { 312 match ty {
314 Ty::Unknown => self.table.new_type_var(), 313 Ty::Unknown => self.table.new_type_var(),
315 Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(Uncertain::Unknown), .. }) => {
316 self.table.new_integer_var()
317 }
318 Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(Uncertain::Unknown), .. }) => {
319 self.table.new_float_var()
320 }
321 _ => ty, 314 _ => ty,
322 } 315 }
323 } 316 }
@@ -383,25 +376,6 @@ impl<'a> InferenceContext<'a> {
383 ) -> Ty { 376 ) -> Ty {
384 match assoc_ty { 377 match assoc_ty {
385 Some(res_assoc_ty) => { 378 Some(res_assoc_ty) => {
386 // FIXME:
387 // Check if inner_ty is is `impl Trait` and contained input TypeAlias id
388 // this is a workaround while Chalk assoc type projection doesn't always work yet,
389 // but once that is fixed I don't think we should keep this
390 // (we'll probably change how associated types are resolved anyway)
391 if let Ty::Opaque(ref predicates) = inner_ty {
392 for p in predicates.iter() {
393 if let GenericPredicate::Projection(projection) = p {
394 if projection.projection_ty.associated_ty == res_assoc_ty {
395 if let ty_app!(_, params) = &projection.ty {
396 if params.len() == 0 {
397 return projection.ty.clone();
398 }
399 }
400 }
401 }
402 }
403 }
404
405 let ty = self.table.new_type_var(); 379 let ty = self.table.new_type_var();
406 let builder = Substs::build_for_def(self.db, res_assoc_ty) 380 let builder = Substs::build_for_def(self.db, res_assoc_ty)
407 .push(inner_ty) 381 .push(inner_ty)
@@ -458,13 +432,13 @@ impl<'a> InferenceContext<'a> {
458 }; 432 };
459 return match resolution { 433 return match resolution {
460 TypeNs::AdtId(AdtId::StructId(strukt)) => { 434 TypeNs::AdtId(AdtId::StructId(strukt)) => {
461 let substs = Ty::substs_from_path(&ctx, path, strukt.into()); 435 let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true);
462 let ty = self.db.ty(strukt.into()); 436 let ty = self.db.ty(strukt.into());
463 let ty = self.insert_type_vars(ty.subst(&substs)); 437 let ty = self.insert_type_vars(ty.subst(&substs));
464 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 438 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
465 } 439 }
466 TypeNs::EnumVariantId(var) => { 440 TypeNs::EnumVariantId(var) => {
467 let substs = Ty::substs_from_path(&ctx, path, var.into()); 441 let substs = Ty::substs_from_path(&ctx, path, var.into(), true);
468 let ty = self.db.ty(var.parent.into()); 442 let ty = self.db.ty(var.parent.into());
469 let ty = self.insert_type_vars(ty.subst(&substs)); 443 let ty = self.insert_type_vars(ty.subst(&substs));
470 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 444 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
@@ -581,13 +555,13 @@ impl<'a> InferenceContext<'a> {
581 } 555 }
582 556
583 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { 557 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
584 let path = path![std::iter::IntoIterator]; 558 let path = path![core::iter::IntoIterator];
585 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; 559 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
586 self.db.trait_data(trait_).associated_type_by_name(&name![Item]) 560 self.db.trait_data(trait_).associated_type_by_name(&name![Item])
587 } 561 }
588 562
589 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { 563 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
590 let path = path![std::ops::Try]; 564 let path = path![core::ops::Try];
591 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; 565 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
592 self.db.trait_data(trait_).associated_type_by_name(&name![Ok]) 566 self.db.trait_data(trait_).associated_type_by_name(&name![Ok])
593 } 567 }
@@ -613,37 +587,37 @@ impl<'a> InferenceContext<'a> {
613 } 587 }
614 588
615 fn resolve_range_full(&self) -> Option<AdtId> { 589 fn resolve_range_full(&self) -> Option<AdtId> {
616 let path = path![std::ops::RangeFull]; 590 let path = path![core::ops::RangeFull];
617 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; 591 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
618 Some(struct_.into()) 592 Some(struct_.into())
619 } 593 }
620 594
621 fn resolve_range(&self) -> Option<AdtId> { 595 fn resolve_range(&self) -> Option<AdtId> {
622 let path = path![std::ops::Range]; 596 let path = path![core::ops::Range];
623 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; 597 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
624 Some(struct_.into()) 598 Some(struct_.into())
625 } 599 }
626 600
627 fn resolve_range_inclusive(&self) -> Option<AdtId> { 601 fn resolve_range_inclusive(&self) -> Option<AdtId> {
628 let path = path![std::ops::RangeInclusive]; 602 let path = path![core::ops::RangeInclusive];
629 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; 603 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
630 Some(struct_.into()) 604 Some(struct_.into())
631 } 605 }
632 606
633 fn resolve_range_from(&self) -> Option<AdtId> { 607 fn resolve_range_from(&self) -> Option<AdtId> {
634 let path = path![std::ops::RangeFrom]; 608 let path = path![core::ops::RangeFrom];
635 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; 609 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
636 Some(struct_.into()) 610 Some(struct_.into())
637 } 611 }
638 612
639 fn resolve_range_to(&self) -> Option<AdtId> { 613 fn resolve_range_to(&self) -> Option<AdtId> {
640 let path = path![std::ops::RangeTo]; 614 let path = path![core::ops::RangeTo];
641 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; 615 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
642 Some(struct_.into()) 616 Some(struct_.into())
643 } 617 }
644 618
645 fn resolve_range_to_inclusive(&self) -> Option<AdtId> { 619 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
646 let path = path![std::ops::RangeToInclusive]; 620 let path = path![core::ops::RangeToInclusive];
647 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?; 621 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
648 Some(struct_.into()) 622 Some(struct_.into())
649 } 623 }
@@ -683,8 +657,8 @@ impl InferTy {
683 fn fallback_value(self) -> Ty { 657 fn fallback_value(self) -> Ty {
684 match self { 658 match self {
685 InferTy::TypeVar(..) => Ty::Unknown, 659 InferTy::TypeVar(..) => Ty::Unknown,
686 InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::i32()))), 660 InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())),
687 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(Uncertain::Known(FloatTy::f64()))), 661 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())),
688 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), 662 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never),
689 } 663 }
690 } 664 }
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 4a98e2deb..9fd310f69 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -18,7 +18,7 @@ use crate::{
18 traits::InEnvironment, 18 traits::InEnvironment,
19 utils::{generics, variant_data, Generics}, 19 utils::{generics, variant_data, Generics},
20 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, 20 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs,
21 TraitRef, Ty, TypeCtor, Uncertain, 21 TraitRef, Ty, TypeCtor,
22}; 22};
23 23
24use super::{ 24use super::{
@@ -426,15 +426,7 @@ impl<'a> InferenceContext<'a> {
426 match &inner_ty { 426 match &inner_ty {
427 // Fast path for builtins 427 // Fast path for builtins
428 Ty::Apply(ApplicationTy { 428 Ty::Apply(ApplicationTy {
429 ctor: 429 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }),
430 TypeCtor::Int(Uncertain::Known(IntTy {
431 signedness: Signedness::Signed,
432 ..
433 })),
434 ..
435 })
436 | Ty::Apply(ApplicationTy {
437 ctor: TypeCtor::Int(Uncertain::Unknown),
438 .. 430 ..
439 }) 431 })
440 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 432 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. })
@@ -577,9 +569,7 @@ impl<'a> InferenceContext<'a> {
577 ); 569 );
578 self.infer_expr( 570 self.infer_expr(
579 *repeat, 571 *repeat,
580 &Expectation::has_type(Ty::simple(TypeCtor::Int(Uncertain::Known( 572 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))),
581 IntTy::usize(),
582 )))),
583 ); 573 );
584 } 574 }
585 } 575 }
@@ -592,13 +582,19 @@ impl<'a> InferenceContext<'a> {
592 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) 582 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
593 } 583 }
594 Literal::ByteString(..) => { 584 Literal::ByteString(..) => {
595 let byte_type = Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::u8()))); 585 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8()));
596 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 586 let array_type = Ty::apply_one(TypeCtor::Array, byte_type);
597 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 587 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type)
598 } 588 }
599 Literal::Char(..) => Ty::simple(TypeCtor::Char), 589 Literal::Char(..) => Ty::simple(TypeCtor::Char),
600 Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int((*ty).into())), 590 Literal::Int(_v, ty) => match ty {
601 Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float((*ty).into())), 591 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())),
592 None => self.table.new_integer_var(),
593 },
594 Literal::Float(_v, ty) => match ty {
595 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())),
596 None => self.table.new_float_var(),
597 },
602 }, 598 },
603 }; 599 };
604 // use a new type variable if we got Ty::Unknown here 600 // use a new type variable if we got Ty::Unknown here
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 1c2e56fb0..1ad0d8397 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -95,7 +95,7 @@ impl<'a> InferenceContext<'a> {
95 // self_subst is just for the parent 95 // self_subst is just for the parent
96 let parent_substs = self_subst.unwrap_or_else(Substs::empty); 96 let parent_substs = self_subst.unwrap_or_else(Substs::empty);
97 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 97 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
98 let substs = Ty::substs_from_path(&ctx, path, typable); 98 let substs = Ty::substs_from_path(&ctx, path, typable, true);
99 let full_substs = Substs::builder(substs.len()) 99 let full_substs = Substs::builder(substs.len())
100 .use_parent_substs(&parent_substs) 100 .use_parent_substs(&parent_substs)
101 .fill(substs.0[parent_substs.len()..].iter().cloned()) 101 .fill(substs.0[parent_substs.len()..].iter().cloned())
@@ -141,6 +141,7 @@ impl<'a> InferenceContext<'a> {
141 def, 141 def,
142 resolved_segment, 142 resolved_segment,
143 remaining_segments_for_ty, 143 remaining_segments_for_ty,
144 true,
144 ); 145 );
145 if let Ty::Unknown = ty { 146 if let Ty::Unknown = ty {
146 return None; 147 return None;
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 9fa8d3bdc..2b9372b4b 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -58,7 +58,7 @@ use ra_db::{impl_intern_key, salsa, CrateId};
58 58
59use crate::{ 59use crate::{
60 db::HirDatabase, 60 db::HirDatabase,
61 primitive::{FloatTy, IntTy, Uncertain}, 61 primitive::{FloatTy, IntTy},
62 utils::{generics, make_mut_slice, Generics}, 62 utils::{generics, make_mut_slice, Generics},
63}; 63};
64use display::HirDisplay; 64use display::HirDisplay;
@@ -87,10 +87,10 @@ pub enum TypeCtor {
87 Char, 87 Char,
88 88
89 /// A primitive integer type. For example, `i32`. 89 /// A primitive integer type. For example, `i32`.
90 Int(Uncertain<IntTy>), 90 Int(IntTy),
91 91
92 /// A primitive floating-point type. For example, `f64`. 92 /// A primitive floating-point type. For example, `f64`.
93 Float(Uncertain<FloatTy>), 93 Float(FloatTy),
94 94
95 /// Structures, enumerations and unions. 95 /// Structures, enumerations and unions.
96 Adt(AdtId), 96 Adt(AdtId),
@@ -147,6 +147,12 @@ pub enum TypeCtor {
147 /// an **application type** like `(Iterator::Item)<T>`. 147 /// an **application type** like `(Iterator::Item)<T>`.
148 AssociatedType(TypeAliasId), 148 AssociatedType(TypeAliasId),
149 149
150 /// This represents a placeholder for an opaque type in situations where we
151 /// don't know the hidden type (i.e. currently almost always). This is
152 /// analogous to the `AssociatedType` type constructor. As with that one,
153 /// these are only produced by Chalk.
154 OpaqueType(OpaqueTyId),
155
150 /// The type of a specific closure. 156 /// The type of a specific closure.
151 /// 157 ///
152 /// The closure signature is stored in a `FnPtr` type in the first type 158 /// The closure signature is stored in a `FnPtr` type in the first type
@@ -194,6 +200,14 @@ impl TypeCtor {
194 let generic_params = generics(db.upcast(), type_alias.into()); 200 let generic_params = generics(db.upcast(), type_alias.into());
195 generic_params.len() 201 generic_params.len()
196 } 202 }
203 TypeCtor::OpaqueType(opaque_ty_id) => {
204 match opaque_ty_id {
205 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
206 let generic_params = generics(db.upcast(), func.into());
207 generic_params.len()
208 }
209 }
210 }
197 TypeCtor::FnPtr { num_args } => num_args as usize + 1, 211 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
198 TypeCtor::Tuple { cardinality } => cardinality as usize, 212 TypeCtor::Tuple { cardinality } => cardinality as usize,
199 } 213 }
@@ -220,6 +234,11 @@ impl TypeCtor {
220 TypeCtor::AssociatedType(type_alias) => { 234 TypeCtor::AssociatedType(type_alias) => {
221 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) 235 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate)
222 } 236 }
237 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
238 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
239 Some(func.lookup(db.upcast()).module(db.upcast()).krate)
240 }
241 },
223 } 242 }
224 } 243 }
225 244
@@ -241,6 +260,7 @@ impl TypeCtor {
241 TypeCtor::Adt(adt) => Some(adt.into()), 260 TypeCtor::Adt(adt) => Some(adt.into()),
242 TypeCtor::FnDef(callable) => Some(callable.into()), 261 TypeCtor::FnDef(callable) => Some(callable.into()),
243 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), 262 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
263 TypeCtor::OpaqueType(_impl_trait_id) => None,
244 } 264 }
245 } 265 }
246} 266}
@@ -254,6 +274,12 @@ pub struct ApplicationTy {
254 pub parameters: Substs, 274 pub parameters: Substs,
255} 275}
256 276
277#[derive(Clone, PartialEq, Eq, Debug, Hash)]
278pub struct OpaqueTy {
279 pub opaque_ty_id: OpaqueTyId,
280 pub parameters: Substs,
281}
282
257/// A "projection" type corresponds to an (unnormalized) 283/// A "projection" type corresponds to an (unnormalized)
258/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 284/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
259/// trait and all its parameters are fully known. 285/// trait and all its parameters are fully known.
@@ -308,6 +334,12 @@ pub enum Ty {
308 /// trait and all its parameters are fully known. 334 /// trait and all its parameters are fully known.
309 Projection(ProjectionTy), 335 Projection(ProjectionTy),
310 336
337 /// An opaque type (`impl Trait`).
338 ///
339 /// This is currently only used for return type impl trait; each instance of
340 /// `impl Trait` in a return type gets its own ID.
341 Opaque(OpaqueTy),
342
311 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 343 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
312 /// {}` when we're type-checking the body of that function. In this 344 /// {}` when we're type-checking the body of that function. In this
313 /// situation, we know this stands for *some* type, but don't know the exact 345 /// situation, we know this stands for *some* type, but don't know the exact
@@ -332,12 +364,6 @@ pub enum Ty {
332 /// didn't seem worth the overhead yet. 364 /// didn't seem worth the overhead yet.
333 Dyn(Arc<[GenericPredicate]>), 365 Dyn(Arc<[GenericPredicate]>),
334 366
335 /// An opaque type (`impl Trait`).
336 ///
337 /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for
338 /// more.
339 Opaque(Arc<[GenericPredicate]>),
340
341 /// A placeholder for a type which could not be computed; this is propagated 367 /// A placeholder for a type which could not be computed; this is propagated
342 /// to avoid useless error messages. Doubles as a placeholder where type 368 /// to avoid useless error messages. Doubles as a placeholder where type
343 /// variables are inserted before type checking, since we want to try to 369 /// variables are inserted before type checking, since we want to try to
@@ -490,7 +516,7 @@ impl Deref for Substs {
490 } 516 }
491} 517}
492 518
493#[derive(Copy, Clone, PartialEq, Eq, Debug)] 519#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
494pub struct Binders<T> { 520pub struct Binders<T> {
495 pub num_binders: usize, 521 pub num_binders: usize,
496 pub value: T, 522 pub value: T,
@@ -534,6 +560,20 @@ impl<T: TypeWalk> Binders<T> {
534 } 560 }
535} 561}
536 562
563impl<T: TypeWalk> TypeWalk for Binders<T> {
564 fn walk(&self, f: &mut impl FnMut(&Ty)) {
565 self.value.walk(f);
566 }
567
568 fn walk_mut_binders(
569 &mut self,
570 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
571 binders: DebruijnIndex,
572 ) {
573 self.value.walk_mut_binders(f, binders.shifted_in())
574 }
575}
576
537/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 577/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
538/// Name to be bikeshedded: TraitBound? TraitImplements? 578/// Name to be bikeshedded: TraitBound? TraitImplements?
539#[derive(Clone, PartialEq, Eq, Debug, Hash)] 579#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -947,11 +987,16 @@ impl TypeWalk for Ty {
947 t.walk(f); 987 t.walk(f);
948 } 988 }
949 } 989 }
950 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 990 Ty::Dyn(predicates) => {
951 for p in predicates.iter() { 991 for p in predicates.iter() {
952 p.walk(f); 992 p.walk(f);
953 } 993 }
954 } 994 }
995 Ty::Opaque(o_ty) => {
996 for t in o_ty.parameters.iter() {
997 t.walk(f);
998 }
999 }
955 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1000 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
956 } 1001 }
957 f(self); 1002 f(self);
@@ -969,13 +1014,48 @@ impl TypeWalk for Ty {
969 Ty::Projection(p_ty) => { 1014 Ty::Projection(p_ty) => {
970 p_ty.parameters.walk_mut_binders(f, binders); 1015 p_ty.parameters.walk_mut_binders(f, binders);
971 } 1016 }
972 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 1017 Ty::Dyn(predicates) => {
973 for p in make_mut_slice(predicates) { 1018 for p in make_mut_slice(predicates) {
974 p.walk_mut_binders(f, binders.shifted_in()); 1019 p.walk_mut_binders(f, binders.shifted_in());
975 } 1020 }
976 } 1021 }
1022 Ty::Opaque(o_ty) => {
1023 o_ty.parameters.walk_mut_binders(f, binders);
1024 }
977 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1025 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
978 } 1026 }
979 f(self, binders); 1027 f(self, binders);
980 } 1028 }
981} 1029}
1030
1031impl<T: TypeWalk> TypeWalk for Vec<T> {
1032 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1033 for t in self {
1034 t.walk(f);
1035 }
1036 }
1037 fn walk_mut_binders(
1038 &mut self,
1039 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1040 binders: DebruijnIndex,
1041 ) {
1042 for t in self {
1043 t.walk_mut_binders(f, binders);
1044 }
1045 }
1046}
1047
1048#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
1049pub enum OpaqueTyId {
1050 ReturnTypeImplTrait(hir_def::FunctionId, u16),
1051}
1052
1053#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1054pub struct ReturnTypeImplTraits {
1055 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
1056}
1057
1058#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1059pub(crate) struct ReturnTypeImplTrait {
1060 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1061}
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 35ac86a46..42713928f 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -21,8 +21,10 @@ use hir_def::{
21 HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, 21 HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
22 UnionId, VariantId, 22 UnionId, VariantId,
23}; 23};
24use hir_expand::name::Name;
24use ra_arena::map::ArenaMap; 25use ra_arena::map::ArenaMap;
25use ra_db::CrateId; 26use ra_db::CrateId;
27use test_utils::mark;
26 28
27use crate::{ 29use crate::{
28 db::HirDatabase, 30 db::HirDatabase,
@@ -31,10 +33,10 @@ use crate::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 34 make_mut_slice, variant_data,
33 }, 35 },
34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, 36 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig,
35 ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 37 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs,
38 TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
36}; 39};
37use hir_expand::name::Name;
38 40
39#[derive(Debug)] 41#[derive(Debug)]
40pub struct TyLoweringContext<'a> { 42pub struct TyLoweringContext<'a> {
@@ -47,7 +49,16 @@ pub struct TyLoweringContext<'a> {
47 /// possible currently, so this should be fine for now. 49 /// possible currently, so this should be fine for now.
48 pub type_param_mode: TypeParamLoweringMode, 50 pub type_param_mode: TypeParamLoweringMode,
49 pub impl_trait_mode: ImplTraitLoweringMode, 51 pub impl_trait_mode: ImplTraitLoweringMode,
50 pub impl_trait_counter: std::cell::Cell<u16>, 52 impl_trait_counter: std::cell::Cell<u16>,
53 /// When turning `impl Trait` into opaque types, we have to collect the
54 /// bounds at the same time to get the IDs correct (without becoming too
55 /// complicated). I don't like using interior mutability (as for the
56 /// counter), but I've tried and failed to make the lifetimes work for
57 /// passing around a `&mut TyLoweringContext`. The core problem is that
58 /// we're grouping the mutable data (the counter and this field) together
59 /// with the immutable context (the references to the DB and resolver).
60 /// Splitting this up would be a possible fix.
61 opaque_type_data: std::cell::RefCell<Vec<ReturnTypeImplTrait>>,
51} 62}
52 63
53impl<'a> TyLoweringContext<'a> { 64impl<'a> TyLoweringContext<'a> {
@@ -56,26 +67,42 @@ impl<'a> TyLoweringContext<'a> {
56 let impl_trait_mode = ImplTraitLoweringMode::Disallowed; 67 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
57 let type_param_mode = TypeParamLoweringMode::Placeholder; 68 let type_param_mode = TypeParamLoweringMode::Placeholder;
58 let in_binders = DebruijnIndex::INNERMOST; 69 let in_binders = DebruijnIndex::INNERMOST;
59 Self { db, resolver, in_binders, impl_trait_mode, impl_trait_counter, type_param_mode } 70 let opaque_type_data = std::cell::RefCell::new(Vec::new());
71 Self {
72 db,
73 resolver,
74 in_binders,
75 impl_trait_mode,
76 impl_trait_counter,
77 type_param_mode,
78 opaque_type_data,
79 }
60 } 80 }
61 81
62 pub fn with_shifted_in<T>( 82 pub fn with_debruijn<T>(
63 &self, 83 &self,
64 debruijn: DebruijnIndex, 84 debruijn: DebruijnIndex,
65 f: impl FnOnce(&TyLoweringContext) -> T, 85 f: impl FnOnce(&TyLoweringContext) -> T,
66 ) -> T { 86 ) -> T {
87 let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new());
67 let new_ctx = Self { 88 let new_ctx = Self {
68 in_binders: self.in_binders.shifted_in_from(debruijn), 89 in_binders: debruijn,
69 impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()), 90 impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()),
91 opaque_type_data: std::cell::RefCell::new(opaque_ty_data_vec),
70 ..*self 92 ..*self
71 }; 93 };
72 let result = f(&new_ctx); 94 let result = f(&new_ctx);
73 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get()); 95 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
96 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
74 result 97 result
75 } 98 }
76 99
77 pub fn shifted_in(self, debruijn: DebruijnIndex) -> Self { 100 pub fn with_shifted_in<T>(
78 Self { in_binders: self.in_binders.shifted_in_from(debruijn), ..self } 101 &self,
102 debruijn: DebruijnIndex,
103 f: impl FnOnce(&TyLoweringContext) -> T,
104 ) -> T {
105 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
79 } 106 }
80 107
81 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self { 108 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
@@ -167,20 +194,44 @@ impl Ty {
167 TypeRef::ImplTrait(bounds) => { 194 TypeRef::ImplTrait(bounds) => {
168 match ctx.impl_trait_mode { 195 match ctx.impl_trait_mode {
169 ImplTraitLoweringMode::Opaque => { 196 ImplTraitLoweringMode::Opaque => {
170 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 197 let idx = ctx.impl_trait_counter.get();
171 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 198 ctx.impl_trait_counter.set(idx + 1);
172 bounds 199
173 .iter() 200 assert!(idx as usize == ctx.opaque_type_data.borrow().len());
174 .flat_map(|b| { 201 // this dance is to make sure the data is in the right
175 GenericPredicate::from_type_bound(ctx, b, self_ty.clone()) 202 // place even if we encounter more opaque types while
176 }) 203 // lowering the bounds
177 .collect() 204 ctx.opaque_type_data
178 }); 205 .borrow_mut()
179 Ty::Opaque(predicates) 206 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) });
207 // We don't want to lower the bounds inside the binders
208 // we're currently in, because they don't end up inside
209 // those binders. E.g. when we have `impl Trait<impl
210 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
211 // to the self parameter from `impl Trait`, and the
212 // bounds aren't actually stored nested within each
213 // other, but separately. So if the `T` refers to a type
214 // parameter of the outer function, it's just one binder
215 // away instead of two.
216 let actual_opaque_type_data = ctx
217 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
218 ReturnTypeImplTrait::from_hir(ctx, &bounds)
219 });
220 ctx.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
221
222 let func = match ctx.resolver.generic_def() {
223 Some(GenericDefId::FunctionId(f)) => f,
224 _ => panic!("opaque impl trait lowering in non-function"),
225 };
226 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx);
227 let generics = generics(ctx.db.upcast(), func.into());
228 let parameters = Substs::bound_vars(&generics, ctx.in_binders);
229 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
180 } 230 }
181 ImplTraitLoweringMode::Param => { 231 ImplTraitLoweringMode::Param => {
182 let idx = ctx.impl_trait_counter.get(); 232 let idx = ctx.impl_trait_counter.get();
183 ctx.impl_trait_counter.set(idx + 1); 233 // FIXME we're probably doing something wrong here
234 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
184 if let Some(def) = ctx.resolver.generic_def() { 235 if let Some(def) = ctx.resolver.generic_def() {
185 let generics = generics(ctx.db.upcast(), def); 236 let generics = generics(ctx.db.upcast(), def);
186 let param = generics 237 let param = generics
@@ -197,7 +248,8 @@ impl Ty {
197 } 248 }
198 ImplTraitLoweringMode::Variable => { 249 ImplTraitLoweringMode::Variable => {
199 let idx = ctx.impl_trait_counter.get(); 250 let idx = ctx.impl_trait_counter.get();
200 ctx.impl_trait_counter.set(idx + 1); 251 // FIXME we're probably doing something wrong here
252 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
201 let (parent_params, self_params, list_params, _impl_trait_params) = 253 let (parent_params, self_params, list_params, _impl_trait_params) =
202 if let Some(def) = ctx.resolver.generic_def() { 254 if let Some(def) = ctx.resolver.generic_def() {
203 let generics = generics(ctx.db.upcast(), def); 255 let generics = generics(ctx.db.upcast(), def);
@@ -271,6 +323,7 @@ impl Ty {
271 resolution: TypeNs, 323 resolution: TypeNs,
272 resolved_segment: PathSegment<'_>, 324 resolved_segment: PathSegment<'_>,
273 remaining_segments: PathSegments<'_>, 325 remaining_segments: PathSegments<'_>,
326 infer_args: bool,
274 ) -> (Ty, Option<TypeNs>) { 327 ) -> (Ty, Option<TypeNs>) {
275 let ty = match resolution { 328 let ty = match resolution {
276 TypeNs::TraitId(trait_) => { 329 TypeNs::TraitId(trait_) => {
@@ -348,9 +401,15 @@ impl Ty {
348 ctx.db.ty(adt.into()).subst(&substs) 401 ctx.db.ty(adt.into()).subst(&substs)
349 } 402 }
350 403
351 TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 404 TypeNs::AdtId(it) => {
352 TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 405 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
353 TypeNs::TypeAliasId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 406 }
407 TypeNs::BuiltinType(it) => {
408 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
409 }
410 TypeNs::TypeAliasId(it) => {
411 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
412 }
354 // FIXME: report error 413 // FIXME: report error
355 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 414 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None),
356 }; 415 };
@@ -376,7 +435,13 @@ impl Ty {
376 ), 435 ),
377 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), 436 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
378 }; 437 };
379 Ty::from_partly_resolved_hir_path(ctx, resolution, resolved_segment, remaining_segments) 438 Ty::from_partly_resolved_hir_path(
439 ctx,
440 resolution,
441 resolved_segment,
442 remaining_segments,
443 false,
444 )
380 } 445 }
381 446
382 fn select_associated_type( 447 fn select_associated_type(
@@ -422,13 +487,14 @@ impl Ty {
422 ctx: &TyLoweringContext<'_>, 487 ctx: &TyLoweringContext<'_>,
423 segment: PathSegment<'_>, 488 segment: PathSegment<'_>,
424 typable: TyDefId, 489 typable: TyDefId,
490 infer_args: bool,
425 ) -> Ty { 491 ) -> Ty {
426 let generic_def = match typable { 492 let generic_def = match typable {
427 TyDefId::BuiltinType(_) => None, 493 TyDefId::BuiltinType(_) => None,
428 TyDefId::AdtId(it) => Some(it.into()), 494 TyDefId::AdtId(it) => Some(it.into()),
429 TyDefId::TypeAliasId(it) => Some(it.into()), 495 TyDefId::TypeAliasId(it) => Some(it.into()),
430 }; 496 };
431 let substs = substs_from_path_segment(ctx, segment, generic_def, false); 497 let substs = substs_from_path_segment(ctx, segment, generic_def, infer_args);
432 ctx.db.ty(typable).subst(&substs) 498 ctx.db.ty(typable).subst(&substs)
433 } 499 }
434 500
@@ -441,6 +507,7 @@ impl Ty {
441 // `ValueTyDefId` is just a convenient way to pass generics and 507 // `ValueTyDefId` is just a convenient way to pass generics and
442 // special-case enum variants 508 // special-case enum variants
443 resolved: ValueTyDefId, 509 resolved: ValueTyDefId,
510 infer_args: bool,
444 ) -> Substs { 511 ) -> Substs {
445 let last = path.segments().last().expect("path should have at least one segment"); 512 let last = path.segments().last().expect("path should have at least one segment");
446 let (segment, generic_def) = match resolved { 513 let (segment, generic_def) = match resolved {
@@ -463,22 +530,27 @@ impl Ty {
463 (segment, Some(var.parent.into())) 530 (segment, Some(var.parent.into()))
464 } 531 }
465 }; 532 };
466 substs_from_path_segment(ctx, segment, generic_def, false) 533 substs_from_path_segment(ctx, segment, generic_def, infer_args)
467 } 534 }
468} 535}
469 536
470pub(super) fn substs_from_path_segment( 537fn substs_from_path_segment(
471 ctx: &TyLoweringContext<'_>, 538 ctx: &TyLoweringContext<'_>,
472 segment: PathSegment<'_>, 539 segment: PathSegment<'_>,
473 def_generic: Option<GenericDefId>, 540 def_generic: Option<GenericDefId>,
474 _add_self_param: bool, 541 infer_args: bool,
475) -> Substs { 542) -> Substs {
476 let mut substs = Vec::new(); 543 let mut substs = Vec::new();
477 let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); 544 let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def));
478 545
479 let (parent_params, self_params, type_params, impl_trait_params) = 546 let (parent_params, self_params, type_params, impl_trait_params) =
480 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 547 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
548 let total_len = parent_params + self_params + type_params + impl_trait_params;
549
481 substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); 550 substs.extend(iter::repeat(Ty::Unknown).take(parent_params));
551
552 let mut had_explicit_args = false;
553
482 if let Some(generic_args) = &segment.args_and_bindings { 554 if let Some(generic_args) = &segment.args_and_bindings {
483 if !generic_args.has_self_type { 555 if !generic_args.has_self_type {
484 substs.extend(iter::repeat(Ty::Unknown).take(self_params)); 556 substs.extend(iter::repeat(Ty::Unknown).take(self_params));
@@ -490,31 +562,35 @@ pub(super) fn substs_from_path_segment(
490 for arg in generic_args.args.iter().skip(skip).take(expected_num) { 562 for arg in generic_args.args.iter().skip(skip).take(expected_num) {
491 match arg { 563 match arg {
492 GenericArg::Type(type_ref) => { 564 GenericArg::Type(type_ref) => {
565 had_explicit_args = true;
493 let ty = Ty::from_hir(ctx, type_ref); 566 let ty = Ty::from_hir(ctx, type_ref);
494 substs.push(ty); 567 substs.push(ty);
495 } 568 }
496 } 569 }
497 } 570 }
498 } 571 }
499 let total_len = parent_params + self_params + type_params + impl_trait_params;
500 // add placeholders for args that were not provided
501 for _ in substs.len()..total_len {
502 substs.push(Ty::Unknown);
503 }
504 assert_eq!(substs.len(), total_len);
505 572
506 // handle defaults 573 // handle defaults. In expression or pattern path segments without
507 if let Some(def_generic) = def_generic { 574 // explicitly specified type arguments, missing type arguments are inferred
508 let default_substs = ctx.db.generic_defaults(def_generic); 575 // (i.e. defaults aren't used).
509 assert_eq!(substs.len(), default_substs.len()); 576 if !infer_args || had_explicit_args {
577 if let Some(def_generic) = def_generic {
578 let default_substs = ctx.db.generic_defaults(def_generic);
579 assert_eq!(total_len, default_substs.len());
510 580
511 for (i, default_ty) in default_substs.iter().enumerate() { 581 for default_ty in default_substs.iter().skip(substs.len()) {
512 if substs[i] == Ty::Unknown { 582 substs.push(default_ty.clone());
513 substs[i] = default_ty.clone();
514 } 583 }
515 } 584 }
516 } 585 }
517 586
587 // add placeholders for args that were not provided
588 // FIXME: emit diagnostics in contexts where this is not allowed
589 for _ in substs.len()..total_len {
590 substs.push(Ty::Unknown);
591 }
592 assert_eq!(substs.len(), total_len);
593
518 Substs(substs.into()) 594 Substs(substs.into())
519} 595}
520 596
@@ -563,9 +639,7 @@ impl TraitRef {
563 segment: PathSegment<'_>, 639 segment: PathSegment<'_>,
564 resolved: TraitId, 640 resolved: TraitId,
565 ) -> Substs { 641 ) -> Substs {
566 let has_self_param = 642 substs_from_path_segment(ctx, segment, Some(resolved.into()), false)
567 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
568 substs_from_path_segment(ctx, segment, Some(resolved.into()), !has_self_param)
569 } 643 }
570 644
571 pub(crate) fn from_type_bound( 645 pub(crate) fn from_type_bound(
@@ -663,6 +737,30 @@ fn assoc_type_bindings_from_type_bound<'a>(
663 }) 737 })
664} 738}
665 739
740impl ReturnTypeImplTrait {
741 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
742 mark::hit!(lower_rpit);
743 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
744 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
745 bounds
746 .iter()
747 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
748 .collect()
749 });
750 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
751 }
752}
753
754fn count_impl_traits(type_ref: &TypeRef) -> usize {
755 let mut count = 0;
756 type_ref.walk(&mut |type_ref| {
757 if matches!(type_ref, TypeRef::ImplTrait(_)) {
758 count += 1;
759 }
760 });
761 count
762}
763
666/// Build the signature of a callable item (function, struct or enum variant). 764/// Build the signature of a callable item (function, struct or enum variant).
667pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDef) -> PolyFnSig { 765pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDef) -> PolyFnSig {
668 match def { 766 match def {
@@ -864,7 +962,9 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
864 .with_impl_trait_mode(ImplTraitLoweringMode::Variable) 962 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
865 .with_type_param_mode(TypeParamLoweringMode::Variable); 963 .with_type_param_mode(TypeParamLoweringMode::Variable);
866 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); 964 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>();
867 let ctx_ret = ctx_params.with_impl_trait_mode(ImplTraitLoweringMode::Opaque); 965 let ctx_ret = TyLoweringContext::new(db, &resolver)
966 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
967 .with_type_param_mode(TypeParamLoweringMode::Variable);
868 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 968 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
869 let generics = generics(db.upcast(), def.into()); 969 let generics = generics(db.upcast(), def.into());
870 let num_binders = generics.len(); 970 let num_binders = generics.len();
@@ -1084,3 +1184,25 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
1084 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value))?, 1184 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value))?,
1085 )) 1185 ))
1086} 1186}
1187
1188pub(crate) fn return_type_impl_traits(
1189 db: &impl HirDatabase,
1190 def: hir_def::FunctionId,
1191) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1192 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1193 let data = db.function_data(def);
1194 let resolver = def.resolver(db.upcast());
1195 let ctx_ret = TyLoweringContext::new(db, &resolver)
1196 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1197 .with_type_param_mode(TypeParamLoweringMode::Variable);
1198 let _ret = Ty::from_hir(&ctx_ret, &data.ret_type);
1199 let generics = generics(db.upcast(), def.into());
1200 let num_binders = generics.len();
1201 let return_type_impl_traits =
1202 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1203 if return_type_impl_traits.impl_traits.is_empty() {
1204 None
1205 } else {
1206 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits)))
1207 }
1208}
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index e19628fdf..e83b39456 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -16,12 +16,8 @@ use rustc_hash::{FxHashMap, FxHashSet};
16 16
17use super::Substs; 17use super::Substs;
18use crate::{ 18use crate::{
19 autoderef, 19 autoderef, db::HirDatabase, primitive::FloatBitness, utils::all_super_traits, ApplicationTy,
20 db::HirDatabase, 20 Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
21 primitive::{FloatBitness, Uncertain},
22 utils::all_super_traits,
23 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty,
24 TypeCtor, TypeWalk,
25}; 21};
26 22
27/// This is used as a key for indexing impls. 23/// This is used as a key for indexing impls.
@@ -147,12 +143,12 @@ impl Ty {
147 } 143 }
148 TypeCtor::Bool => lang_item_crate!("bool"), 144 TypeCtor::Bool => lang_item_crate!("bool"),
149 TypeCtor::Char => lang_item_crate!("char"), 145 TypeCtor::Char => lang_item_crate!("char"),
150 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { 146 TypeCtor::Float(f) => match f.bitness {
151 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 147 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
152 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), 148 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
153 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), 149 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
154 }, 150 },
155 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()), 151 TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()),
156 TypeCtor::Str => lang_item_crate!("str_alloc", "str"), 152 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
157 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), 153 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
158 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), 154 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
diff --git a/crates/ra_hir_ty/src/primitive.rs b/crates/ra_hir_ty/src/primitive.rs
index 02a8179d9..37966b709 100644
--- a/crates/ra_hir_ty/src/primitive.rs
+++ b/crates/ra_hir_ty/src/primitive.rs
@@ -7,42 +7,6 @@ use std::fmt;
7 7
8pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; 8pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness};
9 9
10#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
11pub enum Uncertain<T> {
12 Unknown,
13 Known(T),
14}
15
16impl From<IntTy> for Uncertain<IntTy> {
17 fn from(ty: IntTy) -> Self {
18 Uncertain::Known(ty)
19 }
20}
21
22impl fmt::Display for Uncertain<IntTy> {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 match *self {
25 Uncertain::Unknown => write!(f, "{{integer}}"),
26 Uncertain::Known(ty) => write!(f, "{}", ty),
27 }
28 }
29}
30
31impl From<FloatTy> for Uncertain<FloatTy> {
32 fn from(ty: FloatTy) -> Self {
33 Uncertain::Known(ty)
34 }
35}
36
37impl fmt::Display for Uncertain<FloatTy> {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 match *self {
40 Uncertain::Unknown => write!(f, "{{float}}"),
41 Uncertain::Known(ty) => write!(f, "{}", ty),
42 }
43 }
44}
45
46#[derive(Copy, Clone, Eq, PartialEq, Hash)] 10#[derive(Copy, Clone, Eq, PartialEq, Hash)]
47pub struct IntTy { 11pub struct IntTy {
48 pub signedness: Signedness, 12 pub signedness: Signedness,
@@ -173,21 +137,3 @@ impl From<BuiltinFloat> for FloatTy {
173 FloatTy { bitness: t.bitness } 137 FloatTy { bitness: t.bitness }
174 } 138 }
175} 139}
176
177impl From<Option<BuiltinInt>> for Uncertain<IntTy> {
178 fn from(t: Option<BuiltinInt>) -> Self {
179 match t {
180 None => Uncertain::Unknown,
181 Some(t) => Uncertain::Known(t.into()),
182 }
183 }
184}
185
186impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
187 fn from(t: Option<BuiltinFloat>) -> Self {
188 match t {
189 None => Uncertain::Unknown,
190 Some(t) => Uncertain::Known(t.into()),
191 }
192 }
193}
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index 8498d3d96..ad04e3e0f 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -7,9 +7,8 @@ use std::{
7 7
8use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; 8use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId};
9use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink}; 9use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink};
10use ra_db::{ 10use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast};
11 salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase, Upcast, 11use rustc_hash::FxHashSet;
12};
13use stdx::format_to; 12use stdx::format_to;
14 13
15use crate::{db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator}; 14use crate::{db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator};
@@ -72,23 +71,12 @@ impl FileLoader for TestDB {
72 fn file_text(&self, file_id: FileId) -> Arc<String> { 71 fn file_text(&self, file_id: FileId) -> Arc<String> {
73 FileLoaderDelegate(self).file_text(file_id) 72 FileLoaderDelegate(self).file_text(file_id)
74 } 73 }
75 fn resolve_relative_path( 74 fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
76 &self, 75 FileLoaderDelegate(self).resolve_path(anchor, path)
77 anchor: FileId,
78 relative_path: &RelativePath,
79 ) -> Option<FileId> {
80 FileLoaderDelegate(self).resolve_relative_path(anchor, relative_path)
81 } 76 }
82 fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { 77 fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
83 FileLoaderDelegate(self).relevant_crates(file_id) 78 FileLoaderDelegate(self).relevant_crates(file_id)
84 } 79 }
85 fn resolve_extern_path(
86 &self,
87 extern_id: ra_db::ExternSourceId,
88 relative_path: &RelativePath,
89 ) -> Option<FileId> {
90 FileLoaderDelegate(self).resolve_extern_path(extern_id, relative_path)
91 }
92} 80}
93 81
94impl TestDB { 82impl TestDB {
diff --git a/crates/ra_hir_ty/src/tests/display_source_code.rs b/crates/ra_hir_ty/src/tests/display_source_code.rs
index 4088b1d22..5dfa0a014 100644
--- a/crates/ra_hir_ty/src/tests/display_source_code.rs
+++ b/crates/ra_hir_ty/src/tests/display_source_code.rs
@@ -29,7 +29,7 @@ fn omit_default_type_parameters() {
29 //- /main.rs 29 //- /main.rs
30 struct Foo<T = u8> { t: T } 30 struct Foo<T = u8> { t: T }
31 fn main() { 31 fn main() {
32 let foo = Foo { t: 5 }; 32 let foo = Foo { t: 5u8 };
33 foo<|>; 33 foo<|>;
34 } 34 }
35 ", 35 ",
@@ -41,7 +41,7 @@ fn omit_default_type_parameters() {
41 //- /main.rs 41 //- /main.rs
42 struct Foo<K, T = u8> { k: K, t: T } 42 struct Foo<K, T = u8> { k: K, t: T }
43 fn main() { 43 fn main() {
44 let foo = Foo { k: 400, t: 5 }; 44 let foo = Foo { k: 400, t: 5u8 };
45 foo<|>; 45 foo<|>;
46 } 46 }
47 ", 47 ",
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 558a70022..804297315 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -184,60 +184,6 @@ fn test() {
184} 184}
185 185
186#[test] 186#[test]
187fn infer_associated_method_generics_with_default_param() {
188 assert_snapshot!(
189 infer(r#"
190struct Gen<T=u32> {
191 val: T
192}
193
194impl<T> Gen<T> {
195 pub fn make() -> Gen<T> {
196 loop { }
197 }
198}
199
200fn test() {
201 let a = Gen::make();
202}
203"#),
204 @r###"
205 80..104 '{ ... }': Gen<T>
206 90..98 'loop { }': !
207 95..98 '{ }': ()
208 118..146 '{ ...e(); }': ()
209 128..129 'a': Gen<u32>
210 132..141 'Gen::make': fn make<u32>() -> Gen<u32>
211 132..143 'Gen::make()': Gen<u32>
212 "###
213 );
214}
215
216#[test]
217fn infer_associated_method_generics_with_default_tuple_param() {
218 let t = type_at(
219 r#"
220//- /main.rs
221struct Gen<T=()> {
222 val: T
223}
224
225impl<T> Gen<T> {
226 pub fn make() -> Gen<T> {
227 loop { }
228 }
229}
230
231fn test() {
232 let a = Gen::make();
233 a.val<|>;
234}
235"#,
236 );
237 assert_eq!(t, "()");
238}
239
240#[test]
241fn infer_associated_method_generics_without_args() { 187fn infer_associated_method_generics_without_args() {
242 assert_snapshot!( 188 assert_snapshot!(
243 infer(r#" 189 infer(r#"
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 88309157b..37659cd02 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -95,7 +95,7 @@ fn foo() {
95fn infer_ranges() { 95fn infer_ranges() {
96 let (db, pos) = TestDB::with_position( 96 let (db, pos) = TestDB::with_position(
97 r#" 97 r#"
98//- /main.rs crate:main deps:std 98//- /main.rs crate:main deps:core
99fn test() { 99fn test() {
100 let a = ..; 100 let a = ..;
101 let b = 1..; 101 let b = 1..;
@@ -108,7 +108,7 @@ fn test() {
108 t<|>; 108 t<|>;
109} 109}
110 110
111//- /std.rs crate:std 111//- /core.rs crate:core
112#[prelude_import] use prelude::*; 112#[prelude_import] use prelude::*;
113mod prelude {} 113mod prelude {}
114 114
@@ -1997,3 +1997,111 @@ fn foo() {
1997 "### 1997 "###
1998 ); 1998 );
1999} 1999}
2000
2001#[test]
2002fn generic_default() {
2003 assert_snapshot!(
2004 infer(r#"
2005struct Thing<T = ()> { t: T }
2006enum OtherThing<T = ()> {
2007 One { t: T },
2008 Two(T),
2009}
2010
2011fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) {
2012 t1.t;
2013 t3.t;
2014 match t2 {
2015 OtherThing::One { t } => { t; },
2016 OtherThing::Two(t) => { t; },
2017 }
2018 match t4 {
2019 OtherThing::One { t } => { t; },
2020 OtherThing::Two(t) => { t; },
2021 }
2022}
2023"#),
2024 @r###"
2025 98..100 't1': Thing<()>
2026 109..111 't2': OtherThing<()>
2027 125..127 't3': Thing<i32>
2028 141..143 't4': OtherThing<i32>
2029 162..385 '{ ... } }': ()
2030 168..170 't1': Thing<()>
2031 168..172 't1.t': ()
2032 178..180 't3': Thing<i32>
2033 178..182 't3.t': i32
2034 188..283 'match ... }': ()
2035 194..196 't2': OtherThing<()>
2036 207..228 'OtherT... { t }': OtherThing<()>
2037 225..226 't': ()
2038 232..238 '{ t; }': ()
2039 234..235 't': ()
2040 248..266 'OtherT...Two(t)': OtherThing<()>
2041 264..265 't': ()
2042 270..276 '{ t; }': ()
2043 272..273 't': ()
2044 288..383 'match ... }': ()
2045 294..296 't4': OtherThing<i32>
2046 307..328 'OtherT... { t }': OtherThing<i32>
2047 325..326 't': i32
2048 332..338 '{ t; }': ()
2049 334..335 't': i32
2050 348..366 'OtherT...Two(t)': OtherThing<i32>
2051 364..365 't': i32
2052 370..376 '{ t; }': ()
2053 372..373 't': i32
2054 "###
2055 );
2056}
2057
2058#[test]
2059fn generic_default_in_struct_literal() {
2060 assert_snapshot!(
2061 infer(r#"
2062struct Thing<T = ()> { t: T }
2063enum OtherThing<T = ()> {
2064 One { t: T },
2065 Two(T),
2066}
2067
2068fn test() {
2069 let x = Thing { t: loop {} };
2070 let y = Thing { t: () };
2071 let z = Thing { t: 1i32 };
2072 if let Thing { t } = z {
2073 t;
2074 }
2075
2076 let a = OtherThing::One { t: 1i32 };
2077 let b = OtherThing::Two(1i32);
2078}
2079"#),
2080 @r###"
2081 100..320 '{ ...32); }': ()
2082 110..111 'x': Thing<!>
2083 114..134 'Thing ...p {} }': Thing<!>
2084 125..132 'loop {}': !
2085 130..132 '{}': ()
2086 144..145 'y': Thing<()>
2087 148..163 'Thing { t: () }': Thing<()>
2088 159..161 '()': ()
2089 173..174 'z': Thing<i32>
2090 177..194 'Thing ...1i32 }': Thing<i32>
2091 188..192 '1i32': i32
2092 200..241 'if let... }': ()
2093 207..218 'Thing { t }': Thing<i32>
2094 215..216 't': i32
2095 221..222 'z': Thing<i32>
2096 223..241 '{ ... }': ()
2097 233..234 't': i32
2098 251..252 'a': OtherThing<i32>
2099 255..282 'OtherT...1i32 }': OtherThing<i32>
2100 276..280 '1i32': i32
2101 292..293 'b': OtherThing<i32>
2102 296..311 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32>
2103 296..317 'OtherT...(1i32)': OtherThing<i32>
2104 312..316 '1i32': i32
2105 "###
2106 );
2107}
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index e8778d419..e81193a3c 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -10,7 +10,7 @@ use super::{infer, infer_with_mismatches, type_at, type_at_pos};
10fn infer_await() { 10fn infer_await() {
11 let (db, pos) = TestDB::with_position( 11 let (db, pos) = TestDB::with_position(
12 r#" 12 r#"
13//- /main.rs crate:main deps:std 13//- /main.rs crate:main deps:core
14 14
15struct IntFuture; 15struct IntFuture;
16 16
@@ -24,7 +24,7 @@ fn test() {
24 v<|>; 24 v<|>;
25} 25}
26 26
27//- /std.rs crate:std 27//- /core.rs crate:core
28#[prelude_import] use future::*; 28#[prelude_import] use future::*;
29mod future { 29mod future {
30 #[lang = "future_trait"] 30 #[lang = "future_trait"]
@@ -42,7 +42,7 @@ mod future {
42fn infer_async() { 42fn infer_async() {
43 let (db, pos) = TestDB::with_position( 43 let (db, pos) = TestDB::with_position(
44 r#" 44 r#"
45//- /main.rs crate:main deps:std 45//- /main.rs crate:main deps:core
46 46
47async fn foo() -> u64 { 47async fn foo() -> u64 {
48 128 48 128
@@ -54,7 +54,7 @@ fn test() {
54 v<|>; 54 v<|>;
55} 55}
56 56
57//- /std.rs crate:std 57//- /core.rs crate:core
58#[prelude_import] use future::*; 58#[prelude_import] use future::*;
59mod future { 59mod future {
60 #[lang = "future_trait"] 60 #[lang = "future_trait"]
@@ -72,7 +72,7 @@ mod future {
72fn infer_desugar_async() { 72fn infer_desugar_async() {
73 let (db, pos) = TestDB::with_position( 73 let (db, pos) = TestDB::with_position(
74 r#" 74 r#"
75//- /main.rs crate:main deps:std 75//- /main.rs crate:main deps:core
76 76
77async fn foo() -> u64 { 77async fn foo() -> u64 {
78 128 78 128
@@ -83,7 +83,7 @@ fn test() {
83 r<|>; 83 r<|>;
84} 84}
85 85
86//- /std.rs crate:std 86//- /core.rs crate:core
87#[prelude_import] use future::*; 87#[prelude_import] use future::*;
88mod future { 88mod future {
89 trait Future { 89 trait Future {
@@ -100,7 +100,7 @@ mod future {
100fn infer_try() { 100fn infer_try() {
101 let (db, pos) = TestDB::with_position( 101 let (db, pos) = TestDB::with_position(
102 r#" 102 r#"
103//- /main.rs crate:main deps:std 103//- /main.rs crate:main deps:core
104 104
105fn test() { 105fn test() {
106 let r: Result<i32, u64> = Result::Ok(1); 106 let r: Result<i32, u64> = Result::Ok(1);
@@ -108,7 +108,7 @@ fn test() {
108 v<|>; 108 v<|>;
109} 109}
110 110
111//- /std.rs crate:std 111//- /core.rs crate:core
112 112
113#[prelude_import] use ops::*; 113#[prelude_import] use ops::*;
114mod ops { 114mod ops {
@@ -140,9 +140,9 @@ mod result {
140fn infer_for_loop() { 140fn infer_for_loop() {
141 let (db, pos) = TestDB::with_position( 141 let (db, pos) = TestDB::with_position(
142 r#" 142 r#"
143//- /main.rs crate:main deps:std 143//- /main.rs crate:main deps:core,alloc
144 144
145use std::collections::Vec; 145use alloc::collections::Vec;
146 146
147fn test() { 147fn test() {
148 let v = Vec::new(); 148 let v = Vec::new();
@@ -152,7 +152,7 @@ fn test() {
152 } 152 }
153} 153}
154 154
155//- /std.rs crate:std 155//- /core.rs crate:core
156 156
157#[prelude_import] use iter::*; 157#[prelude_import] use iter::*;
158mod iter { 158mod iter {
@@ -161,6 +161,8 @@ mod iter {
161 } 161 }
162} 162}
163 163
164//- /alloc.rs crate:alloc deps:core
165
164mod collections { 166mod collections {
165 struct Vec<T> {} 167 struct Vec<T> {}
166 impl<T> Vec<T> { 168 impl<T> Vec<T> {
@@ -168,7 +170,7 @@ mod collections {
168 fn push(&mut self, t: T) { } 170 fn push(&mut self, t: T) { }
169 } 171 }
170 172
171 impl<T> crate::iter::IntoIterator for Vec<T> { 173 impl<T> IntoIterator for Vec<T> {
172 type Item=T; 174 type Item=T;
173 } 175 }
174} 176}
@@ -1110,7 +1112,6 @@ fn test() {
1110} 1112}
1111 1113
1112#[test] 1114#[test]
1113#[ignore]
1114fn impl_trait() { 1115fn impl_trait() {
1115 assert_snapshot!( 1116 assert_snapshot!(
1116 infer(r#" 1117 infer(r#"
@@ -1161,6 +1162,95 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
1161} 1162}
1162 1163
1163#[test] 1164#[test]
1165fn simple_return_pos_impl_trait() {
1166 mark::check!(lower_rpit);
1167 assert_snapshot!(
1168 infer(r#"
1169trait Trait<T> {
1170 fn foo(&self) -> T;
1171}
1172fn bar() -> impl Trait<u64> { loop {} }
1173
1174fn test() {
1175 let a = bar();
1176 a.foo();
1177}
1178"#),
1179 @r###"
1180 30..34 'self': &Self
1181 72..83 '{ loop {} }': !
1182 74..81 'loop {}': !
1183 79..81 '{}': ()
1184 95..130 '{ ...o(); }': ()
1185 105..106 'a': impl Trait<u64>
1186 109..112 'bar': fn bar() -> impl Trait<u64>
1187 109..114 'bar()': impl Trait<u64>
1188 120..121 'a': impl Trait<u64>
1189 120..127 'a.foo()': u64
1190 "###
1191 );
1192}
1193
1194#[test]
1195fn more_return_pos_impl_trait() {
1196 assert_snapshot!(
1197 infer(r#"
1198trait Iterator {
1199 type Item;
1200 fn next(&mut self) -> Self::Item;
1201}
1202trait Trait<T> {
1203 fn foo(&self) -> T;
1204}
1205fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} }
1206fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} }
1207
1208fn test() {
1209 let (a, b) = bar();
1210 a.next().foo();
1211 b.foo();
1212 let (c, d) = baz(1u128);
1213 c.next().foo();
1214 d.foo();
1215}
1216"#),
1217 @r###"
1218 50..54 'self': &mut Self
1219 102..106 'self': &Self
1220 185..196 '{ loop {} }': ({unknown}, {unknown})
1221 187..194 'loop {}': !
1222 192..194 '{}': ()
1223 207..208 't': T
1224 269..280 '{ loop {} }': ({unknown}, {unknown})
1225 271..278 'loop {}': !
1226 276..278 '{}': ()
1227 292..414 '{ ...o(); }': ()
1228 302..308 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1229 303..304 'a': impl Iterator<Item = impl Trait<u32>>
1230 306..307 'b': impl Trait<u64>
1231 311..314 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1232 311..316 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1233 322..323 'a': impl Iterator<Item = impl Trait<u32>>
1234 322..330 'a.next()': impl Trait<u32>
1235 322..336 'a.next().foo()': u32
1236 342..343 'b': impl Trait<u64>
1237 342..349 'b.foo()': u64
1238 359..365 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1239 360..361 'c': impl Iterator<Item = impl Trait<u128>>
1240 363..364 'd': impl Trait<u128>
1241 368..371 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1242 368..378 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1243 372..377 '1u128': u128
1244 384..385 'c': impl Iterator<Item = impl Trait<u128>>
1245 384..392 'c.next()': impl Trait<u128>
1246 384..398 'c.next().foo()': u128
1247 404..405 'd': impl Trait<u128>
1248 404..411 'd.foo()': u128
1249 "###
1250 );
1251}
1252
1253#[test]
1164fn dyn_trait() { 1254fn dyn_trait() {
1165 assert_snapshot!( 1255 assert_snapshot!(
1166 infer(r#" 1256 infer(r#"
@@ -1718,33 +1808,33 @@ fn test() {
1718} 1808}
1719"#), 1809"#),
1720 @r###" 1810 @r###"
172165..69 'self': &Self 1811 65..69 'self': &Self
1722166..170 'self': Self 1812 166..170 'self': Self
1723172..176 'args': Args 1813 172..176 'args': Args
1724240..244 'self': &Foo 1814 240..244 'self': &Foo
1725255..257 '{}': () 1815 255..257 '{}': ()
1726335..336 'f': F 1816 335..336 'f': F
1727355..357 '{}': () 1817 355..357 '{}': ()
1728444..690 '{ ...o(); }': () 1818 444..690 '{ ...o(); }': ()
1729454..459 'lazy1': Lazy<Foo, fn() -> T> 1819 454..459 'lazy1': Lazy<Foo, || -> Foo>
1730476..485 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> 1820 476..485 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo>
1731476..493 'Lazy::...| Foo)': Lazy<Foo, fn() -> T> 1821 476..493 'Lazy::...| Foo)': Lazy<Foo, || -> Foo>
1732486..492 '|| Foo': || -> T 1822 486..492 '|| Foo': || -> Foo
1733489..492 'Foo': Foo 1823 489..492 'Foo': Foo
1734503..505 'r1': {unknown} 1824 503..505 'r1': usize
1735508..513 'lazy1': Lazy<Foo, fn() -> T> 1825 508..513 'lazy1': Lazy<Foo, || -> Foo>
1736508..519 'lazy1.foo()': {unknown} 1826 508..519 'lazy1.foo()': usize
1737561..576 'make_foo_fn_ptr': fn() -> Foo 1827 561..576 'make_foo_fn_ptr': fn() -> Foo
1738592..603 'make_foo_fn': fn make_foo_fn() -> Foo 1828 592..603 'make_foo_fn': fn make_foo_fn() -> Foo
1739613..618 'lazy2': Lazy<Foo, fn() -> T> 1829 613..618 'lazy2': Lazy<Foo, fn() -> Foo>
1740635..644 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> 1830 635..644 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo>
1741635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> T> 1831 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo>
1742645..660 'make_foo_fn_ptr': fn() -> Foo 1832 645..660 'make_foo_fn_ptr': fn() -> Foo
1743671..673 'r2': {unknown} 1833 671..673 'r2': {unknown}
1744676..681 'lazy2': Lazy<Foo, fn() -> T> 1834 676..681 'lazy2': Lazy<Foo, fn() -> Foo>
1745676..687 'lazy2.foo()': {unknown} 1835 676..687 'lazy2.foo()': {unknown}
1746550..552 '{}': () 1836 550..552 '{}': ()
1747"### 1837 "###
1748 ); 1838 );
1749} 1839}
1750 1840
@@ -2758,12 +2848,12 @@ fn test() {
2758fn integer_range_iterate() { 2848fn integer_range_iterate() {
2759 let t = type_at( 2849 let t = type_at(
2760 r#" 2850 r#"
2761//- /main.rs crate:main deps:std 2851//- /main.rs crate:main deps:core
2762fn test() { 2852fn test() {
2763 for x in 0..100 { x<|>; } 2853 for x in 0..100 { x<|>; }
2764} 2854}
2765 2855
2766//- /std.rs crate:std 2856//- /core.rs crate:core
2767pub mod ops { 2857pub mod ops {
2768 pub struct Range<Idx> { 2858 pub struct Range<Idx> {
2769 pub start: Idx, 2859 pub start: Idx,
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 61de3cc30..a72a82f5a 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -4,7 +4,7 @@ use std::sync::Arc;
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, GenericArg, TypeName};
7use chalk_solve::rust_ir::{self, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use hir_def::{ 9use hir_def::{
10 lang_item::{lang_attr, LangItemTarget}, 10 lang_item::{lang_attr, LangItemTarget},
@@ -100,6 +100,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
100 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { 100 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
101 self.db.associated_ty_value(self.krate, id) 101 self.db.associated_ty_value(self.krate, id)
102 } 102 }
103
103 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> { 104 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> {
104 vec![] 105 vec![]
105 } 106 }
@@ -130,11 +131,34 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
130 self.db.program_clauses_for_chalk_env(self.krate, environment.clone()) 131 self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
131 } 132 }
132 133
133 fn opaque_ty_data( 134 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
134 &self, 135 let interned_id = crate::db::InternedOpaqueTyId::from(id);
135 _id: chalk_ir::OpaqueTyId<Interner>, 136 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
136 ) -> Arc<rust_ir::OpaqueTyDatum<Interner>> { 137 let (func, idx) = match full_id {
137 unimplemented!() 138 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx),
139 };
140 let datas =
141 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits");
142 let data = &datas.value.impl_traits[idx as usize];
143 let bound = OpaqueTyDatumBound {
144 bounds: make_binders(
145 data.bounds
146 .value
147 .iter()
148 .cloned()
149 .filter(|b| !b.is_error())
150 .map(|b| b.to_chalk(self.db))
151 .collect(),
152 1,
153 ),
154 };
155 let num_vars = datas.num_binders;
156 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) })
157 }
158
159 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
160 // FIXME: actually provide the hidden type; it is relevant for auto traits
161 Ty::Unknown.to_chalk(self.db)
138 } 162 }
139 163
140 fn force_impl_for( 164 fn force_impl_for(
@@ -150,10 +174,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
150 // FIXME: implement actual object safety 174 // FIXME: implement actual object safety
151 true 175 true
152 } 176 }
153
154 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
155 Ty::Unknown.to_chalk(self.db)
156 }
157} 177}
158 178
159pub(crate) fn program_clauses_for_chalk_env_query( 179pub(crate) fn program_clauses_for_chalk_env_query(
@@ -460,6 +480,18 @@ impl From<crate::traits::GlobalImplId> for ImplId {
460 } 480 }
461} 481}
462 482
483impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
484 fn from(id: OpaqueTyId) -> Self {
485 InternKey::from_intern_id(id.0)
486 }
487}
488
489impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
490 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
491 chalk_ir::OpaqueTyId(id.as_intern_id())
492 }
493}
494
463impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { 495impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId {
464 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { 496 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self {
465 Self::from_intern_id(id.0) 497 Self::from_intern_id(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 e27074ba6..56aab640c 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -22,6 +22,8 @@ pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interne
22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
23pub type FnDefId = chalk_ir::FnDefId<Interner>; 23pub type FnDefId = chalk_ir::FnDefId<Interner>;
24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
25pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
26pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
25 27
26impl chalk_ir::interner::Interner for Interner { 28impl chalk_ir::interner::Interner for Interner {
27 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc? 29 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 5f6daf842..18e5c9c16 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -14,10 +14,10 @@ use ra_db::salsa::InternKey;
14 14
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, 17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness},
18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation},
19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, 19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -68,7 +68,16 @@ impl ToChalk for Ty {
68 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) }; 68 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) };
69 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 69 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
70 } 70 }
71 Ty::Opaque(_) | Ty::Unknown => { 71 Ty::Opaque(opaque_ty) => {
72 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
73 let substitution = opaque_ty.parameters.to_chalk(db);
74 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
75 opaque_ty_id,
76 substitution,
77 }))
78 .intern(&Interner)
79 }
80 Ty::Unknown => {
72 let substitution = chalk_ir::Substitution::empty(&Interner); 81 let substitution = chalk_ir::Substitution::empty(&Interner);
73 let name = TypeName::Error; 82 let name = TypeName::Error;
74 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 83 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
@@ -98,7 +107,11 @@ impl ToChalk for Ty {
98 let parameters = from_chalk(db, proj.substitution); 107 let parameters = from_chalk(db, proj.substitution);
99 Ty::Projection(ProjectionTy { associated_ty, parameters }) 108 Ty::Projection(ProjectionTy { associated_ty, parameters })
100 } 109 }
101 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), 110 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
111 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
112 let parameters = from_chalk(db, opaque_ty.substitution);
113 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
114 }
102 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { 115 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => {
103 let parameters: Substs = from_chalk(db, substitution); 116 let parameters: Substs = from_chalk(db, substitution);
104 Ty::Apply(ApplicationTy { 117 Ty::Apply(ApplicationTy {
@@ -204,6 +217,21 @@ impl ToChalk for hir_def::TraitId {
204 } 217 }
205} 218}
206 219
220impl ToChalk for OpaqueTyId {
221 type Chalk = chalk_ir::OpaqueTyId<Interner>;
222
223 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> {
224 db.intern_impl_trait_id(self).into()
225 }
226
227 fn from_chalk(
228 db: &dyn HirDatabase,
229 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
230 ) -> OpaqueTyId {
231 db.lookup_intern_impl_trait_id(opaque_ty_id.into())
232 }
233}
234
207impl ToChalk for TypeCtor { 235impl ToChalk for TypeCtor {
208 type Chalk = TypeName<Interner>; 236 type Chalk = TypeName<Interner>;
209 237
@@ -214,13 +242,18 @@ impl ToChalk for TypeCtor {
214 TypeName::AssociatedType(type_id) 242 TypeName::AssociatedType(type_id)
215 } 243 }
216 244
245 TypeCtor::OpaqueType(impl_trait_id) => {
246 let id = impl_trait_id.to_chalk(db);
247 TypeName::OpaqueType(id)
248 }
249
217 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), 250 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
218 TypeCtor::Char => TypeName::Scalar(Scalar::Char), 251 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
219 TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)), 252 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
220 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) => { 253 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
221 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) 254 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
222 } 255 }
223 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) => { 256 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
224 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) 257 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
225 } 258 }
226 259
@@ -235,9 +268,7 @@ impl ToChalk for TypeCtor {
235 } 268 }
236 TypeCtor::Never => TypeName::Never, 269 TypeCtor::Never => TypeName::Never,
237 270
238 TypeCtor::Int(Uncertain::Unknown) 271 TypeCtor::Adt(_)
239 | TypeCtor::Float(Uncertain::Unknown)
240 | TypeCtor::Adt(_)
241 | TypeCtor::Array 272 | TypeCtor::Array
242 | TypeCtor::FnPtr { .. } 273 | TypeCtor::FnPtr { .. }
243 | TypeCtor::Closure { .. } => { 274 | TypeCtor::Closure { .. } => {
@@ -252,23 +283,25 @@ impl ToChalk for TypeCtor {
252 match type_name { 283 match type_name {
253 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 284 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
254 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 285 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
255 TypeName::OpaqueType(_) => unreachable!(), 286 TypeName::OpaqueType(opaque_type_id) => {
287 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
288 }
256 289
257 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, 290 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
258 TypeName::Scalar(Scalar::Char) => TypeCtor::Char, 291 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
259 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { 292 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy {
260 signedness: Signedness::Signed, 293 signedness: Signedness::Signed,
261 bitness: bitness_from_chalk_int(int_ty), 294 bitness: bitness_from_chalk_int(int_ty),
262 })), 295 }),
263 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { 296 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy {
264 signedness: Signedness::Unsigned, 297 signedness: Signedness::Unsigned,
265 bitness: bitness_from_chalk_uint(uint_ty), 298 bitness: bitness_from_chalk_uint(uint_ty),
266 })), 299 }),
267 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { 300 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
268 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) 301 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })
269 } 302 }
270 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { 303 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
271 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) 304 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })
272 } 305 }
273 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, 306 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
274 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), 307 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
@@ -447,6 +480,11 @@ impl ToChalk for GenericPredicate {
447 let ty = from_chalk(db, projection_eq.ty); 480 let ty = from_chalk(db, projection_eq.ty);
448 GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty }) 481 GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty })
449 } 482 }
483
484 chalk_ir::WhereClause::LifetimeOutlives(_) => {
485 // we shouldn't get these from Chalk
486 panic!("encountered LifetimeOutlives from Chalk")
487 }
450 } 488 }
451 } 489 }
452} 490}
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index d88828c7c..556af7098 100644
--- a/crates/ra_hir_ty/src/traits/chalk/tls.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs
@@ -69,6 +69,11 @@ impl DebugContext<'_> {
69 let name = self.0.type_alias_data(type_alias).name.clone(); 69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?; 70 write!(f, "{}::{}", trait_name, name)?;
71 } 71 }
72 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 }
76 },
72 TypeCtor::Closure { def, expr } => { 77 TypeCtor::Closure { def, expr } => {
73 write!(f, "{{closure {:?} in ", expr.into_raw())?; 78 write!(f, "{{closure {:?} in ", expr.into_raw())?;
74 match def { 79 match def {