aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lower.rs')
-rw-r--r--crates/hir_ty/src/lower.rs66
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;
12use hir_def::{ 12use 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)