diff options
Diffstat (limited to 'crates/hir_ty/src/lower.rs')
-rw-r--r-- | crates/hir_ty/src/lower.rs | 66 |
1 files changed, 40 insertions, 26 deletions
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) |