diff options
author | Florian Diebold <[email protected]> | 2020-01-25 22:38:33 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-02-07 17:28:10 +0000 |
commit | 16c69374471a0072541c21a5551b4fd97f7e12ba (patch) | |
tree | 72564c6b99eb6f1aaf44f740d654b1725daed0c2 /crates/ra_hir_ty/src/lower.rs | |
parent | 93aa166748eef9560df2435391dc3f3b53f8262d (diff) |
Lower impl trait to variables, move away from using placeholders where they don't belong
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 263 |
1 files changed, 141 insertions, 122 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 6f7681475..006101f2f 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -28,32 +28,62 @@ use crate::{ | |||
28 | variant_data, | 28 | variant_data, |
29 | }, | 29 | }, |
30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, | 30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
31 | Ty, TypeCtor, TypeWalk, | 31 | Ty, TypeCtor, PolyFnSig, Binders, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #[derive(Clone, Debug)] | 34 | #[derive(Debug)] |
35 | pub struct TyLoweringContext<'a, DB: HirDatabase> { | 35 | pub struct TyLoweringContext<'a, DB: HirDatabase> { |
36 | pub db: &'a DB, | 36 | pub db: &'a DB, |
37 | pub resolver: &'a Resolver, | 37 | pub resolver: &'a Resolver, |
38 | /// Note: Conceptually, it's thinkable that we could be in a location where | ||
39 | /// some type params are quantified universally (and should be represented | ||
40 | /// as placeholders), and others are quantified existentially (and should be | ||
41 | /// converted to variables). I think in practice, this isn't possible | ||
42 | /// currently, so this should be fine for now. | ||
43 | pub type_param_mode: TypeParamLoweringMode, | ||
38 | pub impl_trait_mode: ImplTraitLoweringMode, | 44 | pub impl_trait_mode: ImplTraitLoweringMode, |
45 | pub impl_trait_counter: std::cell::Cell<u16>, | ||
39 | } | 46 | } |
40 | 47 | ||
41 | #[derive(Clone, Debug)] | 48 | impl<'a, DB: HirDatabase> TyLoweringContext<'a, DB> { |
49 | pub fn new(db: &'a DB, resolver: &'a Resolver) -> Self { | ||
50 | let impl_trait_counter = std::cell::Cell::new(0); | ||
51 | let impl_trait_mode = ImplTraitLoweringMode::Disallowed; | ||
52 | let type_param_mode = TypeParamLoweringMode::Placeholder; | ||
53 | Self { db, resolver, impl_trait_mode, impl_trait_counter, type_param_mode } | ||
54 | } | ||
55 | |||
56 | pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self { | ||
57 | Self { impl_trait_mode, ..self } | ||
58 | } | ||
59 | |||
60 | pub fn with_type_param_mode(self, type_param_mode: TypeParamLoweringMode) -> Self { | ||
61 | Self { type_param_mode, ..self } | ||
62 | } | ||
63 | } | ||
64 | |||
65 | #[derive(Copy, Clone, Debug)] | ||
42 | pub enum ImplTraitLoweringMode { | 66 | pub enum ImplTraitLoweringMode { |
43 | /// `impl Trait` gets lowered into an opaque type that doesn't unify with | 67 | /// `impl Trait` gets lowered into an opaque type that doesn't unify with |
44 | /// anything except itself. This is used in places where values flow 'out', | 68 | /// anything except itself. This is used in places where values flow 'out', |
45 | /// i.e. for arguments of the function we're currently checking, and return | 69 | /// i.e. for arguments of the function we're currently checking, and return |
46 | /// types of functions we're calling. | 70 | /// types of functions we're calling. |
47 | Opaque, | 71 | Opaque, |
48 | /// `impl Trait` gets lowered into a placeholder that can unify with some | 72 | /// `impl Trait` gets lowered into a variable that can unify with some |
49 | /// type. This is used in places where values flow 'in', i.e. for arguments | 73 | /// type. This is used in places where values flow 'in', i.e. for arguments |
50 | /// of functions we're calling, and the return type of the function we're | 74 | /// of functions we're calling, and the return type of the function we're |
51 | /// currently checking. | 75 | /// currently checking. |
52 | Placeholder, | 76 | Variable, |
53 | /// `impl Trait` is disallowed and will be an error. | 77 | /// `impl Trait` is disallowed and will be an error. |
54 | Disallowed, | 78 | Disallowed, |
55 | } | 79 | } |
56 | 80 | ||
81 | #[derive(Copy, Clone, Debug)] | ||
82 | pub enum TypeParamLoweringMode { | ||
83 | Placeholder, | ||
84 | Variable, | ||
85 | } | ||
86 | |||
57 | impl Ty { | 87 | impl Ty { |
58 | pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self { | 88 | pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self { |
59 | match type_ref { | 89 | match type_ref { |
@@ -101,17 +131,25 @@ impl Ty { | |||
101 | let self_ty = Ty::Bound(0); | 131 | let self_ty = Ty::Bound(0); |
102 | let predicates = bounds | 132 | let predicates = bounds |
103 | .iter() | 133 | .iter() |
104 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) | 134 | .flat_map(|b| { |
135 | GenericPredicate::from_type_bound(ctx, b, self_ty.clone()) | ||
136 | }) | ||
105 | .collect(); | 137 | .collect(); |
106 | Ty::Opaque(predicates) | 138 | Ty::Opaque(predicates) |
107 | }, | 139 | } |
108 | ImplTraitLoweringMode::Placeholder => { | 140 | ImplTraitLoweringMode::Variable => { |
109 | todo!() | 141 | let idx = ctx.impl_trait_counter.get(); |
110 | }, | 142 | ctx.impl_trait_counter.set(idx + 1); |
143 | let generics = | ||
144 | generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); | ||
145 | let (self_params, list_params, impl_trait_params) = generics.provenance_split(); | ||
146 | assert!((idx as usize) < impl_trait_params); | ||
147 | Ty::Bound(idx as u32 + self_params as u32 + list_params as u32) | ||
148 | } | ||
111 | ImplTraitLoweringMode::Disallowed => { | 149 | ImplTraitLoweringMode::Disallowed => { |
112 | // FIXME: report error | 150 | // FIXME: report error |
113 | Ty::Unknown | 151 | Ty::Unknown |
114 | }, | 152 | } |
115 | } | 153 | } |
116 | } | 154 | } |
117 | TypeRef::Error => Ty::Unknown, | 155 | TypeRef::Error => Ty::Unknown, |
@@ -205,12 +243,31 @@ impl Ty { | |||
205 | let generics = | 243 | let generics = |
206 | generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); | 244 | generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); |
207 | let idx = generics.param_idx(param_id); | 245 | let idx = generics.param_idx(param_id); |
208 | // FIXME: maybe return name in resolution? | 246 | match ctx.type_param_mode { |
209 | let name = generics.param_name(param_id); | 247 | TypeParamLoweringMode::Placeholder => { |
210 | Ty::Param { idx, name } | 248 | // FIXME: maybe return name in resolution? |
249 | let name = generics.param_name(param_id); | ||
250 | Ty::Param { idx, name } | ||
251 | }, | ||
252 | TypeParamLoweringMode::Variable => Ty::Bound(idx), | ||
253 | } | ||
211 | } | 254 | } |
212 | TypeNs::SelfType(impl_id) => ctx.db.impl_self_ty(impl_id).clone(), | 255 | TypeNs::SelfType(impl_id) => { |
213 | TypeNs::AdtSelfType(adt) => ctx.db.ty(adt.into()), | 256 | let generics = generics(ctx.db, impl_id.into()); |
257 | let substs = match ctx.type_param_mode { | ||
258 | TypeParamLoweringMode::Placeholder => Substs::identity(&generics), | ||
259 | TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), | ||
260 | }; | ||
261 | ctx.db.impl_self_ty(impl_id).subst(&substs) | ||
262 | }, | ||
263 | TypeNs::AdtSelfType(adt) => { | ||
264 | let generics = generics(ctx.db, adt.into()); | ||
265 | let substs = match ctx.type_param_mode { | ||
266 | TypeParamLoweringMode::Placeholder => Substs::identity(&generics), | ||
267 | TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), | ||
268 | }; | ||
269 | ctx.db.ty(adt.into()).subst(&substs) | ||
270 | }, | ||
214 | 271 | ||
215 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), | 272 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), |
216 | TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), | 273 | TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), |
@@ -341,7 +398,7 @@ pub(super) fn substs_from_path_segment( | |||
341 | // Self type as an implicit first type parameter, but it can't be | 398 | // Self type as an implicit first type parameter, but it can't be |
342 | // actually provided in the type arguments | 399 | // actually provided in the type arguments |
343 | // (well, actually sometimes it can, in the form of type-relative paths: `<Foo as Default>::default()`) | 400 | // (well, actually sometimes it can, in the form of type-relative paths: `<Foo as Default>::default()`) |
344 | // TODO handle this using type param provenance | 401 | // TODO handle this using type param provenance (if there's a self param, and not one provided, add unknown) |
345 | substs.push(Ty::Unknown); | 402 | substs.push(Ty::Unknown); |
346 | } | 403 | } |
347 | if let Some(generic_args) = &segment.args_and_bindings { | 404 | if let Some(generic_args) = &segment.args_and_bindings { |
@@ -493,7 +550,7 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
493 | } | 550 | } |
494 | 551 | ||
495 | /// Build the signature of a callable item (function, struct or enum variant). | 552 | /// Build the signature of a callable item (function, struct or enum variant). |
496 | pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | 553 | pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig { |
497 | match def { | 554 | match def { |
498 | CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), | 555 | CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), |
499 | CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), | 556 | CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), |
@@ -513,11 +570,7 @@ pub(crate) fn field_types_query( | |||
513 | VariantId::EnumVariantId(it) => it.parent.resolver(db), | 570 | VariantId::EnumVariantId(it) => it.parent.resolver(db), |
514 | }; | 571 | }; |
515 | let mut res = ArenaMap::default(); | 572 | let mut res = ArenaMap::default(); |
516 | let ctx = TyLoweringContext { | 573 | let ctx = TyLoweringContext::new(db, &resolver); |
517 | db, | ||
518 | resolver: &resolver, | ||
519 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
520 | }; | ||
521 | for (field_id, field_data) in var_data.fields().iter() { | 574 | for (field_id, field_data) in var_data.fields().iter() { |
522 | res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) | 575 | res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) |
523 | } | 576 | } |
@@ -538,11 +591,7 @@ pub(crate) fn generic_predicates_for_param_query( | |||
538 | param_idx: u32, | 591 | param_idx: u32, |
539 | ) -> Arc<[GenericPredicate]> { | 592 | ) -> Arc<[GenericPredicate]> { |
540 | let resolver = def.resolver(db); | 593 | let resolver = def.resolver(db); |
541 | let ctx = TyLoweringContext { | 594 | let ctx = TyLoweringContext::new(db, &resolver); |
542 | db, | ||
543 | resolver: &resolver, | ||
544 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
545 | }; | ||
546 | resolver | 595 | resolver |
547 | .where_predicates_in_scope() | 596 | .where_predicates_in_scope() |
548 | // we have to filter out all other predicates *first*, before attempting to lower them | 597 | // we have to filter out all other predicates *first*, before attempting to lower them |
@@ -562,8 +611,7 @@ pub(crate) fn generic_predicates_for_param_recover( | |||
562 | 611 | ||
563 | impl TraitEnvironment { | 612 | impl TraitEnvironment { |
564 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { | 613 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { |
565 | let ctx = | 614 | let ctx = TyLoweringContext::new(db, &resolver); |
566 | TyLoweringContext { db, resolver, impl_trait_mode: ImplTraitLoweringMode::Disallowed }; | ||
567 | let predicates = resolver | 615 | let predicates = resolver |
568 | .where_predicates_in_scope() | 616 | .where_predicates_in_scope() |
569 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | 617 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) |
@@ -579,11 +627,7 @@ pub(crate) fn generic_predicates_query( | |||
579 | def: GenericDefId, | 627 | def: GenericDefId, |
580 | ) -> Arc<[GenericPredicate]> { | 628 | ) -> Arc<[GenericPredicate]> { |
581 | let resolver = def.resolver(db); | 629 | let resolver = def.resolver(db); |
582 | let ctx = TyLoweringContext { | 630 | let ctx = TyLoweringContext::new(db, &resolver); |
583 | db, | ||
584 | resolver: &resolver, | ||
585 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
586 | }; | ||
587 | resolver | 631 | resolver |
588 | .where_predicates_in_scope() | 632 | .where_predicates_in_scope() |
589 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | 633 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) |
@@ -593,11 +637,7 @@ pub(crate) fn generic_predicates_query( | |||
593 | /// Resolve the default type params from generics | 637 | /// Resolve the default type params from generics |
594 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { | 638 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { |
595 | let resolver = def.resolver(db); | 639 | let resolver = def.resolver(db); |
596 | let ctx = TyLoweringContext { | 640 | let ctx = TyLoweringContext::new(db, &resolver); |
597 | db, | ||
598 | resolver: &resolver, | ||
599 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
600 | }; | ||
601 | let generic_params = generics(db, def.into()); | 641 | let generic_params = generics(db, def.into()); |
602 | 642 | ||
603 | let defaults = generic_params | 643 | let defaults = generic_params |
@@ -608,56 +648,46 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) - | |||
608 | Substs(defaults) | 648 | Substs(defaults) |
609 | } | 649 | } |
610 | 650 | ||
611 | fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { | 651 | fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> PolyFnSig { |
612 | let data = db.function_data(def); | 652 | let data = db.function_data(def); |
613 | let resolver = def.resolver(db); | 653 | let resolver = def.resolver(db); |
614 | let ctx_params = TyLoweringContext { | 654 | let ctx_params = TyLoweringContext::new(db, &resolver) |
615 | db, | 655 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) |
616 | resolver: &resolver, | 656 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
617 | impl_trait_mode: ImplTraitLoweringMode::Placeholder, | ||
618 | }; | ||
619 | let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); | 657 | let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); |
620 | let ctx_ret = TyLoweringContext { | 658 | let ctx_ret = ctx_params.with_impl_trait_mode(ImplTraitLoweringMode::Opaque); |
621 | db, | ||
622 | resolver: &resolver, | ||
623 | impl_trait_mode: ImplTraitLoweringMode::Opaque, | ||
624 | }; | ||
625 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); | 659 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); |
626 | FnSig::from_params_and_return(params, ret) | 660 | let generics = generics(db, def.into()); |
661 | let num_binders = generics.len(); | ||
662 | Binders::new(num_binders, FnSig::from_params_and_return(params, ret)) | ||
627 | } | 663 | } |
628 | 664 | ||
629 | /// Build the declared type of a function. This should not need to look at the | 665 | /// Build the declared type of a function. This should not need to look at the |
630 | /// function body. | 666 | /// function body. |
631 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { | 667 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Binders<Ty> { |
632 | let generics = generics(db, def.into()); | 668 | let generics = generics(db, def.into()); |
633 | let substs = Substs::identity(&generics); | 669 | let substs = Substs::bound_vars(&generics); |
634 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 670 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) |
635 | } | 671 | } |
636 | 672 | ||
637 | /// Build the declared type of a const. | 673 | /// Build the declared type of a const. |
638 | fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { | 674 | fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Binders<Ty> { |
639 | let data = db.const_data(def); | 675 | let data = db.const_data(def); |
676 | let generics = generics(db, def.into()); | ||
640 | let resolver = def.resolver(db); | 677 | let resolver = def.resolver(db); |
641 | let ctx = TyLoweringContext { | 678 | let ctx = TyLoweringContext::new(db, &resolver) |
642 | db, | 679 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
643 | resolver: &resolver, | ||
644 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
645 | }; | ||
646 | 680 | ||
647 | Ty::from_hir(&ctx, &data.type_ref) | 681 | Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref)) |
648 | } | 682 | } |
649 | 683 | ||
650 | /// Build the declared type of a static. | 684 | /// Build the declared type of a static. |
651 | fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { | 685 | fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Binders<Ty> { |
652 | let data = db.static_data(def); | 686 | let data = db.static_data(def); |
653 | let resolver = def.resolver(db); | 687 | let resolver = def.resolver(db); |
654 | let ctx = TyLoweringContext { | 688 | let ctx = TyLoweringContext::new(db, &resolver); |
655 | db, | ||
656 | resolver: &resolver, | ||
657 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
658 | }; | ||
659 | 689 | ||
660 | Ty::from_hir(&ctx, &data.type_ref) | 690 | Binders::new(0, Ty::from_hir(&ctx, &data.type_ref)) |
661 | } | 691 | } |
662 | 692 | ||
663 | /// Build the declared type of a static. | 693 | /// Build the declared type of a static. |
@@ -671,79 +701,71 @@ fn type_for_builtin(def: BuiltinType) -> Ty { | |||
671 | }) | 701 | }) |
672 | } | 702 | } |
673 | 703 | ||
674 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { | 704 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFnSig { |
675 | let struct_data = db.struct_data(def.into()); | 705 | let struct_data = db.struct_data(def.into()); |
676 | let fields = struct_data.variant_data.fields(); | 706 | let fields = struct_data.variant_data.fields(); |
677 | let resolver = def.resolver(db); | 707 | let resolver = def.resolver(db); |
678 | let ctx = TyLoweringContext { | 708 | let ctx = TyLoweringContext::new(db, &resolver) |
679 | db, | 709 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
680 | resolver: &resolver, | ||
681 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
682 | }; | ||
683 | let params = | 710 | let params = |
684 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 711 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
685 | let ret = type_for_adt(db, def.into()); | 712 | let ret = type_for_adt(db, def.into()); |
686 | FnSig::from_params_and_return(params, ret) | 713 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value)) |
687 | } | 714 | } |
688 | 715 | ||
689 | /// Build the type of a tuple struct constructor. | 716 | /// Build the type of a tuple struct constructor. |
690 | fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { | 717 | fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Binders<Ty> { |
691 | let struct_data = db.struct_data(def.into()); | 718 | let struct_data = db.struct_data(def.into()); |
692 | if struct_data.variant_data.is_unit() { | 719 | if struct_data.variant_data.is_unit() { |
693 | return type_for_adt(db, def.into()); // Unit struct | 720 | return type_for_adt(db, def.into()); // Unit struct |
694 | } | 721 | } |
695 | let generics = generics(db, def.into()); | 722 | let generics = generics(db, def.into()); |
696 | let substs = Substs::identity(&generics); | 723 | let substs = Substs::bound_vars(&generics); |
697 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 724 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) |
698 | } | 725 | } |
699 | 726 | ||
700 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { | 727 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> PolyFnSig { |
701 | let enum_data = db.enum_data(def.parent); | 728 | let enum_data = db.enum_data(def.parent); |
702 | let var_data = &enum_data.variants[def.local_id]; | 729 | let var_data = &enum_data.variants[def.local_id]; |
703 | let fields = var_data.variant_data.fields(); | 730 | let fields = var_data.variant_data.fields(); |
704 | let resolver = def.parent.resolver(db); | 731 | let resolver = def.parent.resolver(db); |
705 | let ctx = TyLoweringContext { | 732 | let ctx = TyLoweringContext::new(db, &resolver); |
706 | db, | ||
707 | resolver: &resolver, | ||
708 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
709 | }; | ||
710 | let params = | 733 | let params = |
711 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 734 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
712 | let generics = generics(db, def.parent.into()); | 735 | let generics = generics(db, def.parent.into()); |
713 | let substs = Substs::identity(&generics); | 736 | let substs = Substs::bound_vars(&generics); |
714 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); | 737 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); |
715 | FnSig::from_params_and_return(params, ret) | 738 | let num_binders = generics.len(); |
739 | Binders::new(num_binders, FnSig::from_params_and_return(params, ret)) | ||
716 | } | 740 | } |
717 | 741 | ||
718 | /// Build the type of a tuple enum variant constructor. | 742 | /// Build the type of a tuple enum variant constructor. |
719 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { | 743 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Binders<Ty> { |
720 | let enum_data = db.enum_data(def.parent); | 744 | let enum_data = db.enum_data(def.parent); |
721 | let var_data = &enum_data.variants[def.local_id].variant_data; | 745 | let var_data = &enum_data.variants[def.local_id].variant_data; |
722 | if var_data.is_unit() { | 746 | if var_data.is_unit() { |
723 | return type_for_adt(db, def.parent.into()); // Unit variant | 747 | return type_for_adt(db, def.parent.into()); // Unit variant |
724 | } | 748 | } |
725 | let generics = generics(db, def.parent.into()); | 749 | let generics = generics(db, def.parent.into()); |
726 | let substs = Substs::identity(&generics); | 750 | let substs = Substs::bound_vars(&generics); |
727 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) | 751 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs)) |
728 | } | 752 | } |
729 | 753 | ||
730 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { | 754 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Binders<Ty> { |
731 | let generics = generics(db, adt.into()); | 755 | let generics = generics(db, adt.into()); |
732 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) | 756 | let substs = Substs::bound_vars(&generics); |
757 | Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) | ||
733 | } | 758 | } |
734 | 759 | ||
735 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { | 760 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Binders<Ty> { |
736 | let generics = generics(db, t.into()); | 761 | let generics = generics(db, t.into()); |
737 | let resolver = t.resolver(db); | 762 | let resolver = t.resolver(db); |
738 | let ctx = TyLoweringContext { | 763 | let ctx = TyLoweringContext::new(db, &resolver) |
739 | db, | 764 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
740 | resolver: &resolver, | ||
741 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
742 | }; | ||
743 | let type_ref = &db.type_alias_data(t).type_ref; | 765 | let type_ref = &db.type_alias_data(t).type_ref; |
744 | let substs = Substs::identity(&generics); | 766 | let substs = Substs::bound_vars(&generics); |
745 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); | 767 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
746 | inner.subst(&substs) | 768 | Binders::new(substs.len(), inner) |
747 | } | 769 | } |
748 | 770 | ||
749 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 771 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
@@ -797,19 +819,20 @@ impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId | |||
797 | /// `struct Foo(usize)`, we have two types: The type of the struct itself, and | 819 | /// `struct Foo(usize)`, we have two types: The type of the struct itself, and |
798 | /// the constructor function `(usize) -> Foo` which lives in the values | 820 | /// the constructor function `(usize) -> Foo` which lives in the values |
799 | /// namespace. | 821 | /// namespace. |
800 | pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { | 822 | pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Binders<Ty> { |
801 | match def { | 823 | match def { |
802 | TyDefId::BuiltinType(it) => type_for_builtin(it), | 824 | TyDefId::BuiltinType(it) => Binders::new(0, type_for_builtin(it)), |
803 | TyDefId::AdtId(it) => type_for_adt(db, it), | 825 | TyDefId::AdtId(it) => type_for_adt(db, it), |
804 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), | 826 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), |
805 | } | 827 | } |
806 | } | 828 | } |
807 | 829 | ||
808 | pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty { | 830 | pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Binders<Ty> { |
809 | Ty::Unknown | 831 | // TODO still need correct number of binders here |
832 | Binders::new(0, Ty::Unknown) | ||
810 | } | 833 | } |
811 | 834 | ||
812 | pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | 835 | pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Binders<Ty> { |
813 | match def { | 836 | match def { |
814 | ValueTyDefId::FunctionId(it) => type_for_fn(db, it), | 837 | ValueTyDefId::FunctionId(it) => type_for_fn(db, it), |
815 | ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), | 838 | ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), |
@@ -819,34 +842,30 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | |||
819 | } | 842 | } |
820 | } | 843 | } |
821 | 844 | ||
822 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { | 845 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Binders<Ty> { |
823 | let impl_data = db.impl_data(impl_id); | 846 | let impl_data = db.impl_data(impl_id); |
824 | let resolver = impl_id.resolver(db); | 847 | let resolver = impl_id.resolver(db); |
825 | let ctx = TyLoweringContext { | 848 | let generics = generics(db, impl_id.into()); |
826 | db, | 849 | let ctx = TyLoweringContext::new(db, &resolver) |
827 | resolver: &resolver, | 850 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
828 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | 851 | Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type)) |
829 | }; | ||
830 | Ty::from_hir(&ctx, &impl_data.target_type) | ||
831 | } | 852 | } |
832 | 853 | ||
833 | pub(crate) fn impl_self_ty_recover( | 854 | pub(crate) fn impl_self_ty_recover( |
834 | _db: &impl HirDatabase, | 855 | db: &impl HirDatabase, |
835 | _cycle: &[String], | 856 | _cycle: &[String], |
836 | _impl_id: &ImplId, | 857 | impl_id: &ImplId, |
837 | ) -> Ty { | 858 | ) -> Binders<Ty> { |
838 | Ty::Unknown | 859 | let generics = generics(db, (*impl_id).into()); |
860 | Binders::new(generics.len(), Ty::Unknown) | ||
839 | } | 861 | } |
840 | 862 | ||
841 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { | 863 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { |
842 | let impl_data = db.impl_data(impl_id); | 864 | let impl_data = db.impl_data(impl_id); |
843 | let resolver = impl_id.resolver(db); | 865 | let resolver = impl_id.resolver(db); |
844 | let ctx = TyLoweringContext { | 866 | let generics = generics(db, impl_id.into()); |
845 | db, | 867 | let ctx = TyLoweringContext::new(db, &resolver); |
846 | resolver: &resolver, | 868 | let self_ty = db.impl_self_ty(impl_id).subst(&Substs::identity(&generics)); |
847 | impl_trait_mode: ImplTraitLoweringMode::Disallowed, | ||
848 | }; | ||
849 | let self_ty = db.impl_self_ty(impl_id); | ||
850 | let target_trait = impl_data.target_trait.as_ref()?; | 869 | let target_trait = impl_data.target_trait.as_ref()?; |
851 | TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) | 870 | TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) |
852 | } | 871 | } |