diff options
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/db.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/display.rs | 39 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 104 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 214 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/primitive.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/display_source_code.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 112 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 174 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/interner.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 74 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/tls.rs | 5 |
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 | ||
28 | scoped-tls = "1" | 28 | scoped-tls = "1" |
29 | 29 | ||
30 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "329b7f3fdd2431ed6f6778cde53f22374c7d094c" } | 30 | chalk-solve = "0.11" |
31 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "329b7f3fdd2431ed6f6778cde53f22374c7d094c" } | 31 | chalk-ir = "0.11" |
32 | 32 | ||
33 | [dev-dependencies] | 33 | [dev-dependencies] |
34 | insta = "0.16.0" | 34 | insta = "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 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{ | 5 | use 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 | }; |
9 | use ra_arena::map::ArenaMap; | 9 | use ra_arena::map::ArenaMap; |
10 | use ra_db::{impl_intern_key, salsa, CrateId, Upcast}; | 10 | use ra_db::{impl_intern_key, salsa, CrateId, Upcast}; |
@@ -13,8 +13,8 @@ use ra_prof::profile; | |||
13 | use crate::{ | 13 | use 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 | }; |
19 | use hir_expand::name::Name; | 19 | use 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)] |
143 | pub struct GlobalTypeParamId(salsa::InternId); | 151 | pub struct GlobalTypeParamId(salsa::InternId); |
144 | impl_intern_key!(GlobalTypeParamId); | 152 | impl_intern_key!(GlobalTypeParamId); |
153 | |||
154 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
155 | pub struct InternedOpaqueTyId(salsa::InternId); | ||
156 | impl_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 | ||
5 | use crate::{ | 5 | use 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 | }; |
9 | use hir_def::{ | 9 | use 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; | |||
39 | use super::{ | 39 | use 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 | }; |
45 | use crate::{ | 44 | use 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 | ||
24 | use super::{ | 24 | use 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 | ||
59 | use crate::{ | 59 | use 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 | }; |
64 | use display::HirDisplay; | 64 | use 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)] | ||
278 | pub 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)] |
494 | pub struct Binders<T> { | 520 | pub 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 | ||
563 | impl<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 | |||
1031 | impl<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)] | ||
1049 | pub enum OpaqueTyId { | ||
1050 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | ||
1051 | } | ||
1052 | |||
1053 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
1054 | pub struct ReturnTypeImplTraits { | ||
1055 | pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, | ||
1056 | } | ||
1057 | |||
1058 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
1059 | pub(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 | }; |
24 | use hir_expand::name::Name; | ||
24 | use ra_arena::map::ArenaMap; | 25 | use ra_arena::map::ArenaMap; |
25 | use ra_db::CrateId; | 26 | use ra_db::CrateId; |
27 | use test_utils::mark; | ||
26 | 28 | ||
27 | use crate::{ | 29 | use 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 | }; |
37 | use hir_expand::name::Name; | ||
38 | 40 | ||
39 | #[derive(Debug)] | 41 | #[derive(Debug)] |
40 | pub struct TyLoweringContext<'a> { | 42 | pub 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 | ||
53 | impl<'a> TyLoweringContext<'a> { | 64 | impl<'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 | ||
470 | pub(super) fn substs_from_path_segment( | 537 | fn 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 | ||
740 | impl 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 | |||
754 | fn 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). |
667 | pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDef) -> PolyFnSig { | 765 | pub 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 | |||
1188 | pub(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 | ||
17 | use super::Substs; | 17 | use super::Substs; |
18 | use crate::{ | 18 | use 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 | ||
8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; | 8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; |
9 | 9 | ||
10 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] | ||
11 | pub enum Uncertain<T> { | ||
12 | Unknown, | ||
13 | Known(T), | ||
14 | } | ||
15 | |||
16 | impl From<IntTy> for Uncertain<IntTy> { | ||
17 | fn from(ty: IntTy) -> Self { | ||
18 | Uncertain::Known(ty) | ||
19 | } | ||
20 | } | ||
21 | |||
22 | impl 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 | |||
31 | impl From<FloatTy> for Uncertain<FloatTy> { | ||
32 | fn from(ty: FloatTy) -> Self { | ||
33 | Uncertain::Known(ty) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl 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)] |
47 | pub struct IntTy { | 11 | pub 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 | |||
177 | impl 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 | |||
186 | impl 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 | ||
8 | use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; | 8 | use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; |
9 | use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink}; | 9 | use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink}; |
10 | use ra_db::{ | 10 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast}; |
11 | salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase, Upcast, | 11 | use rustc_hash::FxHashSet; |
12 | }; | ||
13 | use stdx::format_to; | 12 | use stdx::format_to; |
14 | 13 | ||
15 | use crate::{db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator}; | 14 | use 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 | ||
94 | impl TestDB { | 82 | impl 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] |
187 | fn infer_associated_method_generics_with_default_param() { | ||
188 | assert_snapshot!( | ||
189 | infer(r#" | ||
190 | struct Gen<T=u32> { | ||
191 | val: T | ||
192 | } | ||
193 | |||
194 | impl<T> Gen<T> { | ||
195 | pub fn make() -> Gen<T> { | ||
196 | loop { } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | fn 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] | ||
217 | fn infer_associated_method_generics_with_default_tuple_param() { | ||
218 | let t = type_at( | ||
219 | r#" | ||
220 | //- /main.rs | ||
221 | struct Gen<T=()> { | ||
222 | val: T | ||
223 | } | ||
224 | |||
225 | impl<T> Gen<T> { | ||
226 | pub fn make() -> Gen<T> { | ||
227 | loop { } | ||
228 | } | ||
229 | } | ||
230 | |||
231 | fn test() { | ||
232 | let a = Gen::make(); | ||
233 | a.val<|>; | ||
234 | } | ||
235 | "#, | ||
236 | ); | ||
237 | assert_eq!(t, "()"); | ||
238 | } | ||
239 | |||
240 | #[test] | ||
241 | fn infer_associated_method_generics_without_args() { | 187 | fn 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() { | |||
95 | fn infer_ranges() { | 95 | fn 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 |
99 | fn test() { | 99 | fn 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::*; |
113 | mod prelude {} | 113 | mod prelude {} |
114 | 114 | ||
@@ -1997,3 +1997,111 @@ fn foo() { | |||
1997 | "### | 1997 | "### |
1998 | ); | 1998 | ); |
1999 | } | 1999 | } |
2000 | |||
2001 | #[test] | ||
2002 | fn generic_default() { | ||
2003 | assert_snapshot!( | ||
2004 | infer(r#" | ||
2005 | struct Thing<T = ()> { t: T } | ||
2006 | enum OtherThing<T = ()> { | ||
2007 | One { t: T }, | ||
2008 | Two(T), | ||
2009 | } | ||
2010 | |||
2011 | fn 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] | ||
2059 | fn generic_default_in_struct_literal() { | ||
2060 | assert_snapshot!( | ||
2061 | infer(r#" | ||
2062 | struct Thing<T = ()> { t: T } | ||
2063 | enum OtherThing<T = ()> { | ||
2064 | One { t: T }, | ||
2065 | Two(T), | ||
2066 | } | ||
2067 | |||
2068 | fn 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}; | |||
10 | fn infer_await() { | 10 | fn 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 | ||
15 | struct IntFuture; | 15 | struct 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::*; |
29 | mod future { | 29 | mod future { |
30 | #[lang = "future_trait"] | 30 | #[lang = "future_trait"] |
@@ -42,7 +42,7 @@ mod future { | |||
42 | fn infer_async() { | 42 | fn 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 | ||
47 | async fn foo() -> u64 { | 47 | async 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::*; |
59 | mod future { | 59 | mod future { |
60 | #[lang = "future_trait"] | 60 | #[lang = "future_trait"] |
@@ -72,7 +72,7 @@ mod future { | |||
72 | fn infer_desugar_async() { | 72 | fn 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 | ||
77 | async fn foo() -> u64 { | 77 | async 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::*; |
88 | mod future { | 88 | mod future { |
89 | trait Future { | 89 | trait Future { |
@@ -100,7 +100,7 @@ mod future { | |||
100 | fn infer_try() { | 100 | fn 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 | ||
105 | fn test() { | 105 | fn 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::*; |
114 | mod ops { | 114 | mod ops { |
@@ -140,9 +140,9 @@ mod result { | |||
140 | fn infer_for_loop() { | 140 | fn 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 | ||
145 | use std::collections::Vec; | 145 | use alloc::collections::Vec; |
146 | 146 | ||
147 | fn test() { | 147 | fn 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::*; |
158 | mod iter { | 158 | mod iter { |
@@ -161,6 +161,8 @@ mod iter { | |||
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
164 | //- /alloc.rs crate:alloc deps:core | ||
165 | |||
164 | mod collections { | 166 | mod 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] | ||
1114 | fn impl_trait() { | 1115 | fn 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] |
1165 | fn simple_return_pos_impl_trait() { | ||
1166 | mark::check!(lower_rpit); | ||
1167 | assert_snapshot!( | ||
1168 | infer(r#" | ||
1169 | trait Trait<T> { | ||
1170 | fn foo(&self) -> T; | ||
1171 | } | ||
1172 | fn bar() -> impl Trait<u64> { loop {} } | ||
1173 | |||
1174 | fn 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] | ||
1195 | fn more_return_pos_impl_trait() { | ||
1196 | assert_snapshot!( | ||
1197 | infer(r#" | ||
1198 | trait Iterator { | ||
1199 | type Item; | ||
1200 | fn next(&mut self) -> Self::Item; | ||
1201 | } | ||
1202 | trait Trait<T> { | ||
1203 | fn foo(&self) -> T; | ||
1204 | } | ||
1205 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } | ||
1206 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } | ||
1207 | |||
1208 | fn 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] | ||
1164 | fn dyn_trait() { | 1254 | fn 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###" |
1721 | 65..69 'self': &Self | 1811 | 65..69 'self': &Self |
1722 | 166..170 'self': Self | 1812 | 166..170 'self': Self |
1723 | 172..176 'args': Args | 1813 | 172..176 'args': Args |
1724 | 240..244 'self': &Foo | 1814 | 240..244 'self': &Foo |
1725 | 255..257 '{}': () | 1815 | 255..257 '{}': () |
1726 | 335..336 'f': F | 1816 | 335..336 'f': F |
1727 | 355..357 '{}': () | 1817 | 355..357 '{}': () |
1728 | 444..690 '{ ...o(); }': () | 1818 | 444..690 '{ ...o(); }': () |
1729 | 454..459 'lazy1': Lazy<Foo, fn() -> T> | 1819 | 454..459 'lazy1': Lazy<Foo, || -> Foo> |
1730 | 476..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> |
1731 | 476..493 'Lazy::...| Foo)': Lazy<Foo, fn() -> T> | 1821 | 476..493 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> |
1732 | 486..492 '|| Foo': || -> T | 1822 | 486..492 '|| Foo': || -> Foo |
1733 | 489..492 'Foo': Foo | 1823 | 489..492 'Foo': Foo |
1734 | 503..505 'r1': {unknown} | 1824 | 503..505 'r1': usize |
1735 | 508..513 'lazy1': Lazy<Foo, fn() -> T> | 1825 | 508..513 'lazy1': Lazy<Foo, || -> Foo> |
1736 | 508..519 'lazy1.foo()': {unknown} | 1826 | 508..519 'lazy1.foo()': usize |
1737 | 561..576 'make_foo_fn_ptr': fn() -> Foo | 1827 | 561..576 'make_foo_fn_ptr': fn() -> Foo |
1738 | 592..603 'make_foo_fn': fn make_foo_fn() -> Foo | 1828 | 592..603 'make_foo_fn': fn make_foo_fn() -> Foo |
1739 | 613..618 'lazy2': Lazy<Foo, fn() -> T> | 1829 | 613..618 'lazy2': Lazy<Foo, fn() -> Foo> |
1740 | 635..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> |
1741 | 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> T> | 1831 | 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> |
1742 | 645..660 'make_foo_fn_ptr': fn() -> Foo | 1832 | 645..660 'make_foo_fn_ptr': fn() -> Foo |
1743 | 671..673 'r2': {unknown} | 1833 | 671..673 'r2': {unknown} |
1744 | 676..681 'lazy2': Lazy<Foo, fn() -> T> | 1834 | 676..681 'lazy2': Lazy<Foo, fn() -> Foo> |
1745 | 676..687 'lazy2.foo()': {unknown} | 1835 | 676..687 'lazy2.foo()': {unknown} |
1746 | 550..552 '{}': () | 1836 | 550..552 '{}': () |
1747 | "### | 1837 | "### |
1748 | ); | 1838 | ); |
1749 | } | 1839 | } |
1750 | 1840 | ||
@@ -2758,12 +2848,12 @@ fn test() { | |||
2758 | fn integer_range_iterate() { | 2848 | fn 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 |
2762 | fn test() { | 2852 | fn 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 |
2767 | pub mod ops { | 2857 | pub 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; | |||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; | 6 | use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; |
7 | use chalk_solve::rust_ir::{self, WellKnownTrait}; | 7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 8 | ||
9 | use hir_def::{ | 9 | use 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 | ||
159 | pub(crate) fn program_clauses_for_chalk_env_query( | 179 | pub(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 | ||
483 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | ||
484 | fn from(id: OpaqueTyId) -> Self { | ||
485 | InternKey::from_intern_id(id.0) | ||
486 | } | ||
487 | } | ||
488 | |||
489 | impl 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 | |||
463 | impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { | 495 | impl 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 | |||
22 | pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; | 22 | pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; |
23 | pub type FnDefId = chalk_ir::FnDefId<Interner>; | 23 | pub type FnDefId = chalk_ir::FnDefId<Interner>; |
24 | pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | 24 | pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; |
25 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
26 | pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | ||
25 | 27 | ||
26 | impl chalk_ir::interner::Interner for Interner { | 28 | impl 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 | ||
15 | use crate::{ | 15 | use 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 | ||
23 | use super::interner::*; | 23 | use 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 | ||
220 | impl 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 | |||
207 | impl ToChalk for TypeCtor { | 235 | impl 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 { |