diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/display.rs | 15 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 1 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 66 | ||||
-rw-r--r-- | crates/hir_ty/src/utils.rs | 24 |
5 files changed, 77 insertions, 39 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index e77481906..0d968cc68 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/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, CallableDefId, FnSig, GenericPredicate, | 6 | db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, |
7 | Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 7 | Lifetime, 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, |
@@ -710,6 +710,19 @@ impl HirDisplay for GenericPredicate { | |||
710 | } | 710 | } |
711 | } | 711 | } |
712 | 712 | ||
713 | impl HirDisplay for Lifetime { | ||
714 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
715 | match self { | ||
716 | Lifetime::Parameter(id) => { | ||
717 | let generics = generics(f.db.upcast(), id.parent); | ||
718 | let param_data = &generics.params.lifetimes[id.local_id]; | ||
719 | write!(f, "{}", ¶m_data.name) | ||
720 | } | ||
721 | Lifetime::Static => write!(f, "'static"), | ||
722 | } | ||
723 | } | ||
724 | } | ||
725 | |||
713 | impl HirDisplay for Obligation { | 726 | impl HirDisplay for Obligation { |
714 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 727 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
715 | match self { | 728 | match self { |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index d7ad198b3..ca005bc99 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -862,6 +862,7 @@ impl<'a> InferenceContext<'a> { | |||
862 | let ty = self.make_ty(type_ref); | 862 | let ty = self.make_ty(type_ref); |
863 | substs.push(ty); | 863 | substs.push(ty); |
864 | } | 864 | } |
865 | GenericArg::Lifetime(_) => {} | ||
865 | } | 866 | } |
866 | } | 867 | } |
867 | }; | 868 | }; |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 5a8c97198..357bd92f9 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -29,8 +29,8 @@ use base_db::{salsa, CrateId}; | |||
29 | use hir_def::{ | 29 | use hir_def::{ |
30 | expr::ExprId, | 30 | expr::ExprId, |
31 | type_ref::{Mutability, Rawness}, | 31 | type_ref::{Mutability, Rawness}, |
32 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, | 32 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, LifetimeParamId, Lookup, |
33 | TypeParamId, | 33 | TraitId, TypeAliasId, TypeParamId, |
34 | }; | 34 | }; |
35 | use itertools::Itertools; | 35 | use itertools::Itertools; |
36 | 36 | ||
@@ -52,6 +52,12 @@ pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironmen | |||
52 | 52 | ||
53 | pub use chalk_ir::{BoundVar, DebruijnIndex}; | 53 | pub use chalk_ir::{BoundVar, DebruijnIndex}; |
54 | 54 | ||
55 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
56 | pub enum Lifetime { | ||
57 | Parameter(LifetimeParamId), | ||
58 | Static, | ||
59 | } | ||
60 | |||
55 | /// A type constructor or type name: this might be something like the primitive | 61 | /// A type constructor or type name: this might be something like the primitive |
56 | /// type `bool`, a struct like `Vec`, or things like function pointers or | 62 | /// type `bool`, a struct like `Vec`, or things like function pointers or |
57 | /// tuples. | 63 | /// tuples. |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 708e2af0f..92f779360 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -12,7 +12,7 @@ use base_db::CrateId; | |||
12 | use hir_def::{ | 12 | use hir_def::{ |
13 | adt::StructKind, | 13 | adt::StructKind, |
14 | builtin_type::BuiltinType, | 14 | builtin_type::BuiltinType, |
15 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget}, | 15 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, |
16 | path::{GenericArg, Path, PathSegment, PathSegments}, | 16 | path::{GenericArg, Path, PathSegment, PathSegments}, |
17 | resolver::{HasResolver, Resolver, TypeNs}, | 17 | resolver::{HasResolver, Resolver, TypeNs}, |
18 | type_ref::{TypeBound, TypeRef}, | 18 | type_ref::{TypeBound, TypeRef}, |
@@ -171,7 +171,7 @@ impl Ty { | |||
171 | let inner_ty = Ty::from_hir(ctx, inner); | 171 | let inner_ty = Ty::from_hir(ctx, inner); |
172 | Ty::apply_one(TypeCtor::Slice, inner_ty) | 172 | Ty::apply_one(TypeCtor::Slice, inner_ty) |
173 | } | 173 | } |
174 | TypeRef::Reference(inner, mutability) => { | 174 | TypeRef::Reference(inner, _, mutability) => { |
175 | let inner_ty = Ty::from_hir(ctx, inner); | 175 | let inner_ty = Ty::from_hir(ctx, inner); |
176 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 176 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
177 | } | 177 | } |
@@ -555,7 +555,7 @@ fn substs_from_path_segment( | |||
555 | 555 | ||
556 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); | 556 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); |
557 | 557 | ||
558 | let mut had_explicit_args = false; | 558 | let mut had_explicit_type_args = false; |
559 | 559 | ||
560 | if let Some(generic_args) = &segment.args_and_bindings { | 560 | if let Some(generic_args) = &segment.args_and_bindings { |
561 | if !generic_args.has_self_type { | 561 | if !generic_args.has_self_type { |
@@ -568,10 +568,11 @@ fn substs_from_path_segment( | |||
568 | for arg in generic_args.args.iter().skip(skip).take(expected_num) { | 568 | for arg in generic_args.args.iter().skip(skip).take(expected_num) { |
569 | match arg { | 569 | match arg { |
570 | GenericArg::Type(type_ref) => { | 570 | GenericArg::Type(type_ref) => { |
571 | had_explicit_args = true; | 571 | had_explicit_type_args = true; |
572 | let ty = Ty::from_hir(ctx, type_ref); | 572 | let ty = Ty::from_hir(ctx, type_ref); |
573 | substs.push(ty); | 573 | substs.push(ty); |
574 | } | 574 | } |
575 | GenericArg::Lifetime(_) => {} | ||
575 | } | 576 | } |
576 | } | 577 | } |
577 | } | 578 | } |
@@ -579,7 +580,7 @@ fn substs_from_path_segment( | |||
579 | // handle defaults. In expression or pattern path segments without | 580 | // handle defaults. In expression or pattern path segments without |
580 | // explicitly specified type arguments, missing type arguments are inferred | 581 | // explicitly specified type arguments, missing type arguments are inferred |
581 | // (i.e. defaults aren't used). | 582 | // (i.e. defaults aren't used). |
582 | if !infer_args || had_explicit_args { | 583 | if !infer_args || had_explicit_type_args { |
583 | if let Some(def_generic) = def_generic { | 584 | if let Some(def_generic) = def_generic { |
584 | let defaults = ctx.db.generic_defaults(def_generic); | 585 | let defaults = ctx.db.generic_defaults(def_generic); |
585 | assert_eq!(total_len, defaults.len()); | 586 | assert_eq!(total_len, defaults.len()); |
@@ -657,7 +658,7 @@ impl TraitRef { | |||
657 | ) -> Option<TraitRef> { | 658 | ) -> Option<TraitRef> { |
658 | match bound { | 659 | match bound { |
659 | TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)), | 660 | TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)), |
660 | TypeBound::Error => None, | 661 | TypeBound::Lifetime(_) | TypeBound::Error => None, |
661 | } | 662 | } |
662 | } | 663 | } |
663 | } | 664 | } |
@@ -667,22 +668,30 @@ impl GenericPredicate { | |||
667 | ctx: &'a TyLoweringContext<'a>, | 668 | ctx: &'a TyLoweringContext<'a>, |
668 | where_predicate: &'a WherePredicate, | 669 | where_predicate: &'a WherePredicate, |
669 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 670 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
670 | let self_ty = match &where_predicate.target { | 671 | match where_predicate { |
671 | WherePredicateTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), | 672 | WherePredicate::TypeBound { target, bound } => { |
672 | WherePredicateTarget::TypeParam(param_id) => { | 673 | let self_ty = match target { |
673 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); | 674 | WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), |
674 | let generics = generics(ctx.db.upcast(), generic_def); | 675 | WherePredicateTypeTarget::TypeParam(param_id) => { |
675 | let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; | 676 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); |
676 | match ctx.type_param_mode { | 677 | let generics = generics(ctx.db.upcast(), generic_def); |
677 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), | 678 | let param_id = |
678 | TypeParamLoweringMode::Variable => { | 679 | hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; |
679 | let idx = generics.param_idx(param_id).expect("matching generics"); | 680 | match ctx.type_param_mode { |
680 | Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) | 681 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), |
682 | TypeParamLoweringMode::Variable => { | ||
683 | let idx = generics.param_idx(param_id).expect("matching generics"); | ||
684 | Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) | ||
685 | } | ||
686 | } | ||
681 | } | 687 | } |
682 | } | 688 | }; |
689 | GenericPredicate::from_type_bound(ctx, bound, self_ty) | ||
690 | .collect::<Vec<_>>() | ||
691 | .into_iter() | ||
683 | } | 692 | } |
684 | }; | 693 | WherePredicate::Lifetime { .. } => vec![].into_iter(), |
685 | GenericPredicate::from_type_bound(ctx, &where_predicate.bound, self_ty) | 694 | } |
686 | } | 695 | } |
687 | 696 | ||
688 | pub(crate) fn from_type_bound<'a>( | 697 | pub(crate) fn from_type_bound<'a>( |
@@ -707,7 +716,7 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
707 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 716 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
708 | let last_segment = match bound { | 717 | let last_segment = match bound { |
709 | TypeBound::Path(path) => path.segments().last(), | 718 | TypeBound::Path(path) => path.segments().last(), |
710 | TypeBound::Error => None, | 719 | TypeBound::Error | TypeBound::Lifetime(_) => None, |
711 | }; | 720 | }; |
712 | last_segment | 721 | last_segment |
713 | .into_iter() | 722 | .into_iter() |
@@ -872,11 +881,16 @@ pub(crate) fn generic_predicates_for_param_query( | |||
872 | resolver | 881 | resolver |
873 | .where_predicates_in_scope() | 882 | .where_predicates_in_scope() |
874 | // we have to filter out all other predicates *first*, before attempting to lower them | 883 | // we have to filter out all other predicates *first*, before attempting to lower them |
875 | .filter(|pred| match &pred.target { | 884 | .filter(|pred| match pred { |
876 | WherePredicateTarget::TypeRef(type_ref) => { | 885 | WherePredicate::TypeBound { |
877 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) | 886 | target: WherePredicateTypeTarget::TypeRef(type_ref), |
878 | } | 887 | .. |
879 | WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id, | 888 | } => Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id), |
889 | WherePredicate::TypeBound { | ||
890 | target: WherePredicateTypeTarget::TypeParam(local_id), | ||
891 | .. | ||
892 | } => *local_id == param_id.local_id, | ||
893 | WherePredicate::Lifetime { .. } => false, | ||
880 | }) | 894 | }) |
881 | .flat_map(|pred| { | 895 | .flat_map(|pred| { |
882 | GenericPredicate::from_where_predicate(&ctx, pred) | 896 | GenericPredicate::from_where_predicate(&ctx, pred) |
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index e3e244268..af880c065 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs | |||
@@ -2,11 +2,10 @@ | |||
2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). | 2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). |
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::generics::WherePredicateTarget; | ||
6 | use hir_def::{ | 5 | use hir_def::{ |
7 | adt::VariantData, | 6 | adt::VariantData, |
8 | db::DefDatabase, | 7 | db::DefDatabase, |
9 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, | 8 | generics::{GenericParams, TypeParamData, TypeParamProvenance, WherePredicateTypeTarget}, |
10 | path::Path, | 9 | path::Path, |
11 | resolver::{HasResolver, TypeNs}, | 10 | resolver::{HasResolver, TypeNs}, |
12 | type_ref::TypeRef, | 11 | type_ref::TypeRef, |
@@ -27,14 +26,19 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { | |||
27 | generic_params | 26 | generic_params |
28 | .where_predicates | 27 | .where_predicates |
29 | .iter() | 28 | .iter() |
30 | .filter_map(|pred| match &pred.target { | 29 | .filter_map(|pred| match pred { |
31 | WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => { | 30 | hir_def::generics::WherePredicate::TypeBound { target, bound } => match target { |
32 | pred.bound.as_path() | 31 | WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) |
33 | } | 32 | if p == &Path::from(name![Self]) => |
34 | WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { | 33 | { |
35 | pred.bound.as_path() | 34 | bound.as_path() |
36 | } | 35 | } |
37 | _ => None, | 36 | WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { |
37 | bound.as_path() | ||
38 | } | ||
39 | _ => None, | ||
40 | }, | ||
41 | hir_def::generics::WherePredicate::Lifetime { .. } => None, | ||
38 | }) | 42 | }) |
39 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { | 43 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { |
40 | Some(TypeNs::TraitId(t)) => Some(t), | 44 | Some(TypeNs::TraitId(t)) => Some(t), |