aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r--crates/ra_hir_ty/src/lower.rs329
1 files changed, 241 insertions, 88 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 35ac86a46..f274579ea 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -5,10 +5,7 @@
5//! - Building the type for an item: This happens through the `type_for_def` query. 5//! - Building the type for an item: This happens through the `type_for_def` query.
6//! 6//!
7//! This usually involves resolving names, collecting generic arguments etc. 7//! This usually involves resolving names, collecting generic arguments etc.
8use std::iter; 8use std::{iter, sync::Arc};
9use std::sync::Arc;
10
11use smallvec::SmallVec;
12 9
13use hir_def::{ 10use hir_def::{
14 adt::StructKind, 11 adt::StructKind,
@@ -21,8 +18,12 @@ use hir_def::{
21 HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, 18 HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
22 UnionId, VariantId, 19 UnionId, VariantId,
23}; 20};
21use hir_expand::name::Name;
24use ra_arena::map::ArenaMap; 22use ra_arena::map::ArenaMap;
25use ra_db::CrateId; 23use ra_db::CrateId;
24use smallvec::SmallVec;
25use stdx::impl_from;
26use test_utils::mark;
26 27
27use crate::{ 28use crate::{
28 db::HirDatabase, 29 db::HirDatabase,
@@ -31,10 +32,10 @@ use crate::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 32 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 33 make_mut_slice, variant_data,
33 }, 34 },
34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, 35 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig,
35 ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 36 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs,
37 TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
36}; 38};
37use hir_expand::name::Name;
38 39
39#[derive(Debug)] 40#[derive(Debug)]
40pub struct TyLoweringContext<'a> { 41pub struct TyLoweringContext<'a> {
@@ -47,7 +48,16 @@ pub struct TyLoweringContext<'a> {
47 /// possible currently, so this should be fine for now. 48 /// possible currently, so this should be fine for now.
48 pub type_param_mode: TypeParamLoweringMode, 49 pub type_param_mode: TypeParamLoweringMode,
49 pub impl_trait_mode: ImplTraitLoweringMode, 50 pub impl_trait_mode: ImplTraitLoweringMode,
50 pub impl_trait_counter: std::cell::Cell<u16>, 51 impl_trait_counter: std::cell::Cell<u16>,
52 /// When turning `impl Trait` into opaque types, we have to collect the
53 /// bounds at the same time to get the IDs correct (without becoming too
54 /// complicated). I don't like using interior mutability (as for the
55 /// counter), but I've tried and failed to make the lifetimes work for
56 /// passing around a `&mut TyLoweringContext`. The core problem is that
57 /// we're grouping the mutable data (the counter and this field) together
58 /// with the immutable context (the references to the DB and resolver).
59 /// Splitting this up would be a possible fix.
60 opaque_type_data: std::cell::RefCell<Vec<ReturnTypeImplTrait>>,
51} 61}
52 62
53impl<'a> TyLoweringContext<'a> { 63impl<'a> TyLoweringContext<'a> {
@@ -56,26 +66,42 @@ impl<'a> TyLoweringContext<'a> {
56 let impl_trait_mode = ImplTraitLoweringMode::Disallowed; 66 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
57 let type_param_mode = TypeParamLoweringMode::Placeholder; 67 let type_param_mode = TypeParamLoweringMode::Placeholder;
58 let in_binders = DebruijnIndex::INNERMOST; 68 let in_binders = DebruijnIndex::INNERMOST;
59 Self { db, resolver, in_binders, impl_trait_mode, impl_trait_counter, type_param_mode } 69 let opaque_type_data = std::cell::RefCell::new(Vec::new());
70 Self {
71 db,
72 resolver,
73 in_binders,
74 impl_trait_mode,
75 impl_trait_counter,
76 type_param_mode,
77 opaque_type_data,
78 }
60 } 79 }
61 80
62 pub fn with_shifted_in<T>( 81 pub fn with_debruijn<T>(
63 &self, 82 &self,
64 debruijn: DebruijnIndex, 83 debruijn: DebruijnIndex,
65 f: impl FnOnce(&TyLoweringContext) -> T, 84 f: impl FnOnce(&TyLoweringContext) -> T,
66 ) -> T { 85 ) -> T {
86 let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new());
67 let new_ctx = Self { 87 let new_ctx = Self {
68 in_binders: self.in_binders.shifted_in_from(debruijn), 88 in_binders: debruijn,
69 impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()), 89 impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()),
90 opaque_type_data: std::cell::RefCell::new(opaque_ty_data_vec),
70 ..*self 91 ..*self
71 }; 92 };
72 let result = f(&new_ctx); 93 let result = f(&new_ctx);
73 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get()); 94 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
95 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
74 result 96 result
75 } 97 }
76 98
77 pub fn shifted_in(self, debruijn: DebruijnIndex) -> Self { 99 pub fn with_shifted_in<T>(
78 Self { in_binders: self.in_binders.shifted_in_from(debruijn), ..self } 100 &self,
101 debruijn: DebruijnIndex,
102 f: impl FnOnce(&TyLoweringContext) -> T,
103 ) -> T {
104 self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
79 } 105 }
80 106
81 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self { 107 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
@@ -150,9 +176,12 @@ impl Ty {
150 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 176 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
151 } 177 }
152 TypeRef::Placeholder => Ty::Unknown, 178 TypeRef::Placeholder => Ty::Unknown,
153 TypeRef::Fn(params) => { 179 TypeRef::Fn(params, is_varargs) => {
154 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 180 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
155 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) 181 Ty::apply(
182 TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs },
183 sig,
184 )
156 } 185 }
157 TypeRef::DynTrait(bounds) => { 186 TypeRef::DynTrait(bounds) => {
158 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 187 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
@@ -167,20 +196,44 @@ impl Ty {
167 TypeRef::ImplTrait(bounds) => { 196 TypeRef::ImplTrait(bounds) => {
168 match ctx.impl_trait_mode { 197 match ctx.impl_trait_mode {
169 ImplTraitLoweringMode::Opaque => { 198 ImplTraitLoweringMode::Opaque => {
170 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 199 let idx = ctx.impl_trait_counter.get();
171 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 200 ctx.impl_trait_counter.set(idx + 1);
172 bounds 201
173 .iter() 202 assert!(idx as usize == ctx.opaque_type_data.borrow().len());
174 .flat_map(|b| { 203 // this dance is to make sure the data is in the right
175 GenericPredicate::from_type_bound(ctx, b, self_ty.clone()) 204 // place even if we encounter more opaque types while
176 }) 205 // lowering the bounds
177 .collect() 206 ctx.opaque_type_data
178 }); 207 .borrow_mut()
179 Ty::Opaque(predicates) 208 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) });
209 // We don't want to lower the bounds inside the binders
210 // we're currently in, because they don't end up inside
211 // those binders. E.g. when we have `impl Trait<impl
212 // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
213 // to the self parameter from `impl Trait`, and the
214 // bounds aren't actually stored nested within each
215 // other, but separately. So if the `T` refers to a type
216 // parameter of the outer function, it's just one binder
217 // away instead of two.
218 let actual_opaque_type_data = ctx
219 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
220 ReturnTypeImplTrait::from_hir(ctx, &bounds)
221 });
222 ctx.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
223
224 let func = match ctx.resolver.generic_def() {
225 Some(GenericDefId::FunctionId(f)) => f,
226 _ => panic!("opaque impl trait lowering in non-function"),
227 };
228 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx);
229 let generics = generics(ctx.db.upcast(), func.into());
230 let parameters = Substs::bound_vars(&generics, ctx.in_binders);
231 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
180 } 232 }
181 ImplTraitLoweringMode::Param => { 233 ImplTraitLoweringMode::Param => {
182 let idx = ctx.impl_trait_counter.get(); 234 let idx = ctx.impl_trait_counter.get();
183 ctx.impl_trait_counter.set(idx + 1); 235 // FIXME we're probably doing something wrong here
236 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
184 if let Some(def) = ctx.resolver.generic_def() { 237 if let Some(def) = ctx.resolver.generic_def() {
185 let generics = generics(ctx.db.upcast(), def); 238 let generics = generics(ctx.db.upcast(), def);
186 let param = generics 239 let param = generics
@@ -197,7 +250,8 @@ impl Ty {
197 } 250 }
198 ImplTraitLoweringMode::Variable => { 251 ImplTraitLoweringMode::Variable => {
199 let idx = ctx.impl_trait_counter.get(); 252 let idx = ctx.impl_trait_counter.get();
200 ctx.impl_trait_counter.set(idx + 1); 253 // FIXME we're probably doing something wrong here
254 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
201 let (parent_params, self_params, list_params, _impl_trait_params) = 255 let (parent_params, self_params, list_params, _impl_trait_params) =
202 if let Some(def) = ctx.resolver.generic_def() { 256 if let Some(def) = ctx.resolver.generic_def() {
203 let generics = generics(ctx.db.upcast(), def); 257 let generics = generics(ctx.db.upcast(), def);
@@ -271,6 +325,7 @@ impl Ty {
271 resolution: TypeNs, 325 resolution: TypeNs,
272 resolved_segment: PathSegment<'_>, 326 resolved_segment: PathSegment<'_>,
273 remaining_segments: PathSegments<'_>, 327 remaining_segments: PathSegments<'_>,
328 infer_args: bool,
274 ) -> (Ty, Option<TypeNs>) { 329 ) -> (Ty, Option<TypeNs>) {
275 let ty = match resolution { 330 let ty = match resolution {
276 TypeNs::TraitId(trait_) => { 331 TypeNs::TraitId(trait_) => {
@@ -284,17 +339,17 @@ impl Ty {
284 TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty); 339 TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty);
285 let ty = if remaining_segments.len() == 1 { 340 let ty = if remaining_segments.len() == 1 {
286 let segment = remaining_segments.first().unwrap(); 341 let segment = remaining_segments.first().unwrap();
287 let associated_ty = associated_type_by_name_including_super_traits( 342 let found = associated_type_by_name_including_super_traits(
288 ctx.db.upcast(), 343 ctx.db,
289 trait_ref.trait_, 344 trait_ref.clone(),
290 &segment.name, 345 &segment.name,
291 ); 346 );
292 match associated_ty { 347 match found {
293 Some(associated_ty) => { 348 Some((super_trait_ref, associated_ty)) => {
294 // FIXME handle type parameters on the segment 349 // FIXME handle type parameters on the segment
295 Ty::Projection(ProjectionTy { 350 Ty::Projection(ProjectionTy {
296 associated_ty, 351 associated_ty,
297 parameters: trait_ref.substs, 352 parameters: super_trait_ref.substs,
298 }) 353 })
299 } 354 }
300 None => { 355 None => {
@@ -348,9 +403,15 @@ impl Ty {
348 ctx.db.ty(adt.into()).subst(&substs) 403 ctx.db.ty(adt.into()).subst(&substs)
349 } 404 }
350 405
351 TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 406 TypeNs::AdtId(it) => {
352 TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 407 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()), 408 }
409 TypeNs::BuiltinType(it) => {
410 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
411 }
412 TypeNs::TypeAliasId(it) => {
413 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
414 }
354 // FIXME: report error 415 // FIXME: report error
355 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 416 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None),
356 }; 417 };
@@ -376,7 +437,13 @@ impl Ty {
376 ), 437 ),
377 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), 438 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
378 }; 439 };
379 Ty::from_partly_resolved_hir_path(ctx, resolution, resolved_segment, remaining_segments) 440 Ty::from_partly_resolved_hir_path(
441 ctx,
442 resolution,
443 resolved_segment,
444 remaining_segments,
445 false,
446 )
380 } 447 }
381 448
382 fn select_associated_type( 449 fn select_associated_type(
@@ -402,6 +469,9 @@ impl Ty {
402 } 469 }
403 TypeParamLoweringMode::Variable => t.substs.clone(), 470 TypeParamLoweringMode::Variable => t.substs.clone(),
404 }; 471 };
472 // We need to shift in the bound vars, since
473 // associated_type_shorthand_candidates does not do that
474 let substs = substs.shift_bound_vars(ctx.in_binders);
405 // FIXME handle type parameters on the segment 475 // FIXME handle type parameters on the segment
406 return Some(Ty::Projection(ProjectionTy { 476 return Some(Ty::Projection(ProjectionTy {
407 associated_ty, 477 associated_ty,
@@ -422,13 +492,14 @@ impl Ty {
422 ctx: &TyLoweringContext<'_>, 492 ctx: &TyLoweringContext<'_>,
423 segment: PathSegment<'_>, 493 segment: PathSegment<'_>,
424 typable: TyDefId, 494 typable: TyDefId,
495 infer_args: bool,
425 ) -> Ty { 496 ) -> Ty {
426 let generic_def = match typable { 497 let generic_def = match typable {
427 TyDefId::BuiltinType(_) => None, 498 TyDefId::BuiltinType(_) => None,
428 TyDefId::AdtId(it) => Some(it.into()), 499 TyDefId::AdtId(it) => Some(it.into()),
429 TyDefId::TypeAliasId(it) => Some(it.into()), 500 TyDefId::TypeAliasId(it) => Some(it.into()),
430 }; 501 };
431 let substs = substs_from_path_segment(ctx, segment, generic_def, false); 502 let substs = substs_from_path_segment(ctx, segment, generic_def, infer_args);
432 ctx.db.ty(typable).subst(&substs) 503 ctx.db.ty(typable).subst(&substs)
433 } 504 }
434 505
@@ -441,6 +512,7 @@ impl Ty {
441 // `ValueTyDefId` is just a convenient way to pass generics and 512 // `ValueTyDefId` is just a convenient way to pass generics and
442 // special-case enum variants 513 // special-case enum variants
443 resolved: ValueTyDefId, 514 resolved: ValueTyDefId,
515 infer_args: bool,
444 ) -> Substs { 516 ) -> Substs {
445 let last = path.segments().last().expect("path should have at least one segment"); 517 let last = path.segments().last().expect("path should have at least one segment");
446 let (segment, generic_def) = match resolved { 518 let (segment, generic_def) = match resolved {
@@ -463,22 +535,27 @@ impl Ty {
463 (segment, Some(var.parent.into())) 535 (segment, Some(var.parent.into()))
464 } 536 }
465 }; 537 };
466 substs_from_path_segment(ctx, segment, generic_def, false) 538 substs_from_path_segment(ctx, segment, generic_def, infer_args)
467 } 539 }
468} 540}
469 541
470pub(super) fn substs_from_path_segment( 542fn substs_from_path_segment(
471 ctx: &TyLoweringContext<'_>, 543 ctx: &TyLoweringContext<'_>,
472 segment: PathSegment<'_>, 544 segment: PathSegment<'_>,
473 def_generic: Option<GenericDefId>, 545 def_generic: Option<GenericDefId>,
474 _add_self_param: bool, 546 infer_args: bool,
475) -> Substs { 547) -> Substs {
476 let mut substs = Vec::new(); 548 let mut substs = Vec::new();
477 let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); 549 let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def));
478 550
479 let (parent_params, self_params, type_params, impl_trait_params) = 551 let (parent_params, self_params, type_params, impl_trait_params) =
480 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 552 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
553 let total_len = parent_params + self_params + type_params + impl_trait_params;
554
481 substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); 555 substs.extend(iter::repeat(Ty::Unknown).take(parent_params));
556
557 let mut had_explicit_args = false;
558
482 if let Some(generic_args) = &segment.args_and_bindings { 559 if let Some(generic_args) = &segment.args_and_bindings {
483 if !generic_args.has_self_type { 560 if !generic_args.has_self_type {
484 substs.extend(iter::repeat(Ty::Unknown).take(self_params)); 561 substs.extend(iter::repeat(Ty::Unknown).take(self_params));
@@ -490,31 +567,37 @@ pub(super) fn substs_from_path_segment(
490 for arg in generic_args.args.iter().skip(skip).take(expected_num) { 567 for arg in generic_args.args.iter().skip(skip).take(expected_num) {
491 match arg { 568 match arg {
492 GenericArg::Type(type_ref) => { 569 GenericArg::Type(type_ref) => {
570 had_explicit_args = true;
493 let ty = Ty::from_hir(ctx, type_ref); 571 let ty = Ty::from_hir(ctx, type_ref);
494 substs.push(ty); 572 substs.push(ty);
495 } 573 }
496 } 574 }
497 } 575 }
498 } 576 }
499 let total_len = parent_params + self_params + type_params + impl_trait_params; 577
578 // handle defaults. In expression or pattern path segments without
579 // explicitly specified type arguments, missing type arguments are inferred
580 // (i.e. defaults aren't used).
581 if !infer_args || had_explicit_args {
582 if let Some(def_generic) = def_generic {
583 let defaults = ctx.db.generic_defaults(def_generic);
584 assert_eq!(total_len, defaults.len());
585
586 for default_ty in defaults.iter().skip(substs.len()) {
587 // each default can depend on the previous parameters
588 let substs_so_far = Substs(substs.clone().into());
589 substs.push(default_ty.clone().subst(&substs_so_far));
590 }
591 }
592 }
593
500 // add placeholders for args that were not provided 594 // add placeholders for args that were not provided
595 // FIXME: emit diagnostics in contexts where this is not allowed
501 for _ in substs.len()..total_len { 596 for _ in substs.len()..total_len {
502 substs.push(Ty::Unknown); 597 substs.push(Ty::Unknown);
503 } 598 }
504 assert_eq!(substs.len(), total_len); 599 assert_eq!(substs.len(), total_len);
505 600
506 // handle defaults
507 if let Some(def_generic) = def_generic {
508 let default_substs = ctx.db.generic_defaults(def_generic);
509 assert_eq!(substs.len(), default_substs.len());
510
511 for (i, default_ty) in default_substs.iter().enumerate() {
512 if substs[i] == Ty::Unknown {
513 substs[i] = default_ty.clone();
514 }
515 }
516 }
517
518 Substs(substs.into()) 601 Substs(substs.into())
519} 602}
520 603
@@ -563,9 +646,7 @@ impl TraitRef {
563 segment: PathSegment<'_>, 646 segment: PathSegment<'_>,
564 resolved: TraitId, 647 resolved: TraitId,
565 ) -> Substs { 648 ) -> Substs {
566 let has_self_param = 649 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 } 650 }
570 651
571 pub(crate) fn from_type_bound( 652 pub(crate) fn from_type_bound(
@@ -632,17 +713,16 @@ fn assoc_type_bindings_from_type_bound<'a>(
632 .flat_map(|segment| segment.args_and_bindings.into_iter()) 713 .flat_map(|segment| segment.args_and_bindings.into_iter())
633 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 714 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
634 .flat_map(move |binding| { 715 .flat_map(move |binding| {
635 let associated_ty = associated_type_by_name_including_super_traits( 716 let found = associated_type_by_name_including_super_traits(
636 ctx.db.upcast(), 717 ctx.db,
637 trait_ref.trait_, 718 trait_ref.clone(),
638 &binding.name, 719 &binding.name,
639 ); 720 );
640 let associated_ty = match associated_ty { 721 let (super_trait_ref, associated_ty) = match found {
641 None => return SmallVec::<[GenericPredicate; 1]>::new(), 722 None => return SmallVec::<[GenericPredicate; 1]>::new(),
642 Some(t) => t, 723 Some(t) => t,
643 }; 724 };
644 let projection_ty = 725 let projection_ty = ProjectionTy { associated_ty, parameters: super_trait_ref.substs };
645 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
646 let mut preds = SmallVec::with_capacity( 726 let mut preds = SmallVec::with_capacity(
647 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), 727 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
648 ); 728 );
@@ -663,12 +743,36 @@ fn assoc_type_bindings_from_type_bound<'a>(
663 }) 743 })
664} 744}
665 745
746impl ReturnTypeImplTrait {
747 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
748 mark::hit!(lower_rpit);
749 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
750 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
751 bounds
752 .iter()
753 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
754 .collect()
755 });
756 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
757 }
758}
759
760fn count_impl_traits(type_ref: &TypeRef) -> usize {
761 let mut count = 0;
762 type_ref.walk(&mut |type_ref| {
763 if matches!(type_ref, TypeRef::ImplTrait(_)) {
764 count += 1;
765 }
766 });
767 count
768}
769
666/// Build the signature of a callable item (function, struct or enum variant). 770/// Build the signature of a callable item (function, struct or enum variant).
667pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDef) -> PolyFnSig { 771pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
668 match def { 772 match def {
669 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), 773 CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
670 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), 774 CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
671 CallableDef::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), 775 CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
672 } 776 }
673} 777}
674 778
@@ -844,17 +948,42 @@ pub(crate) fn generic_predicates_query(
844} 948}
845 949
846/// Resolve the default type params from generics 950/// Resolve the default type params from generics
847pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> Substs { 951pub(crate) fn generic_defaults_query(
952 db: &dyn HirDatabase,
953 def: GenericDefId,
954) -> Arc<[Binders<Ty>]> {
848 let resolver = def.resolver(db.upcast()); 955 let resolver = def.resolver(db.upcast());
849 let ctx = TyLoweringContext::new(db, &resolver); 956 let ctx =
957 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
850 let generic_params = generics(db.upcast(), def); 958 let generic_params = generics(db.upcast(), def);
851 959
852 let defaults = generic_params 960 let defaults = generic_params
853 .iter() 961 .iter()
854 .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t))) 962 .enumerate()
963 .map(|(idx, (_, p))| {
964 let mut ty = p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t));
965
966 // Each default can only refer to previous parameters.
967 ty.walk_mut_binders(
968 &mut |ty, binders| match ty {
969 Ty::Bound(BoundVar { debruijn, index }) if *debruijn == binders => {
970 if *index >= idx {
971 // type variable default referring to parameter coming
972 // after it. This is forbidden (FIXME: report
973 // diagnostic)
974 *ty = Ty::Unknown;
975 }
976 }
977 _ => {}
978 },
979 DebruijnIndex::INNERMOST,
980 );
981
982 Binders::new(idx, ty)
983 })
855 .collect(); 984 .collect();
856 985
857 Substs(defaults) 986 defaults
858} 987}
859 988
860fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { 989fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
@@ -864,11 +993,13 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
864 .with_impl_trait_mode(ImplTraitLoweringMode::Variable) 993 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
865 .with_type_param_mode(TypeParamLoweringMode::Variable); 994 .with_type_param_mode(TypeParamLoweringMode::Variable);
866 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); 995 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); 996 let ctx_ret = TyLoweringContext::new(db, &resolver)
997 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
998 .with_type_param_mode(TypeParamLoweringMode::Variable);
868 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 999 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
869 let generics = generics(db.upcast(), def.into()); 1000 let generics = generics(db.upcast(), def.into());
870 let num_binders = generics.len(); 1001 let num_binders = generics.len();
871 Binders::new(num_binders, FnSig::from_params_and_return(params, ret)) 1002 Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs))
872} 1003}
873 1004
874/// Build the declared type of a function. This should not need to look at the 1005/// Build the declared type of a function. This should not need to look at the
@@ -919,7 +1050,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
919 let params = 1050 let params =
920 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1051 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
921 let ret = type_for_adt(db, def.into()); 1052 let ret = type_for_adt(db, def.into());
922 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value)) 1053 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false))
923} 1054}
924 1055
925/// Build the type of a tuple struct constructor. 1056/// Build the type of a tuple struct constructor.
@@ -943,7 +1074,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
943 let params = 1074 let params =
944 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1075 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
945 let ret = type_for_adt(db, def.parent.into()); 1076 let ret = type_for_adt(db, def.parent.into());
946 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value)) 1077 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false))
947} 1078}
948 1079
949/// Build the type of a tuple enum variant constructor. 1080/// Build the type of a tuple enum variant constructor.
@@ -976,31 +1107,31 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
976} 1107}
977 1108
978#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1109#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
979pub enum CallableDef { 1110pub enum CallableDefId {
980 FunctionId(FunctionId), 1111 FunctionId(FunctionId),
981 StructId(StructId), 1112 StructId(StructId),
982 EnumVariantId(EnumVariantId), 1113 EnumVariantId(EnumVariantId),
983} 1114}
984impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId); 1115impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
985 1116
986impl CallableDef { 1117impl CallableDefId {
987 pub fn krate(self, db: &dyn HirDatabase) -> CrateId { 1118 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
988 let db = db.upcast(); 1119 let db = db.upcast();
989 match self { 1120 match self {
990 CallableDef::FunctionId(f) => f.lookup(db).module(db), 1121 CallableDefId::FunctionId(f) => f.lookup(db).module(db),
991 CallableDef::StructId(s) => s.lookup(db).container.module(db), 1122 CallableDefId::StructId(s) => s.lookup(db).container.module(db),
992 CallableDef::EnumVariantId(e) => e.parent.lookup(db).container.module(db), 1123 CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container.module(db),
993 } 1124 }
994 .krate 1125 .krate
995 } 1126 }
996} 1127}
997 1128
998impl From<CallableDef> for GenericDefId { 1129impl From<CallableDefId> for GenericDefId {
999 fn from(def: CallableDef) -> GenericDefId { 1130 fn from(def: CallableDefId) -> GenericDefId {
1000 match def { 1131 match def {
1001 CallableDef::FunctionId(f) => f.into(), 1132 CallableDefId::FunctionId(f) => f.into(),
1002 CallableDef::StructId(s) => s.into(), 1133 CallableDefId::StructId(s) => s.into(),
1003 CallableDef::EnumVariantId(e) => e.into(), 1134 CallableDefId::EnumVariantId(e) => e.into(),
1004 } 1135 }
1005 } 1136 }
1006} 1137}
@@ -1011,7 +1142,7 @@ pub enum TyDefId {
1011 AdtId(AdtId), 1142 AdtId(AdtId),
1012 TypeAliasId(TypeAliasId), 1143 TypeAliasId(TypeAliasId),
1013} 1144}
1014impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); 1145impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1015 1146
1016#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1147#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1017pub enum ValueTyDefId { 1148pub enum ValueTyDefId {
@@ -1021,7 +1152,7 @@ pub enum ValueTyDefId {
1021 ConstId(ConstId), 1152 ConstId(ConstId),
1022 StaticId(StaticId), 1153 StaticId(StaticId),
1023} 1154}
1024impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId); 1155impl_from!(FunctionId, StructId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1025 1156
1026/// Build the declared type of an item. This depends on the namespace; e.g. for 1157/// Build the declared type of an item. This depends on the namespace; e.g. for
1027/// `struct Foo(usize)`, we have two types: The type of the struct itself, and 1158/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
@@ -1084,3 +1215,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))?, 1215 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value))?,
1085 )) 1216 ))
1086} 1217}
1218
1219pub(crate) fn return_type_impl_traits(
1220 db: &dyn HirDatabase,
1221 def: hir_def::FunctionId,
1222) -> Option<Arc<Binders<ReturnTypeImplTraits>>> {
1223 // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1224 let data = db.function_data(def);
1225 let resolver = def.resolver(db.upcast());
1226 let ctx_ret = TyLoweringContext::new(db, &resolver)
1227 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1228 .with_type_param_mode(TypeParamLoweringMode::Variable);
1229 let _ret = Ty::from_hir(&ctx_ret, &data.ret_type);
1230 let generics = generics(db.upcast(), def.into());
1231 let num_binders = generics.len();
1232 let return_type_impl_traits =
1233 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1234 if return_type_impl_traits.impl_traits.is_empty() {
1235 None
1236 } else {
1237 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits)))
1238 }
1239}