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.rs110
1 files changed, 93 insertions, 17 deletions
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 8a22d9ea3..c99dd8d0a 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -5,12 +5,14 @@
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::cell::{Cell, RefCell};
8use std::{iter, sync::Arc}; 9use std::{iter, sync::Arc};
9 10
10use base_db::CrateId; 11use base_db::CrateId;
11use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety}; 12use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety};
12use hir_def::{ 13use hir_def::{
13 adt::StructKind, 14 adt::StructKind,
15 body::{Expander, LowerCtx},
14 builtin_type::BuiltinType, 16 builtin_type::BuiltinType,
15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, 17 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
16 path::{GenericArg, Path, PathSegment, PathSegments}, 18 path::{GenericArg, Path, PathSegment, PathSegments},
@@ -20,20 +22,22 @@ use hir_def::{
20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, 22 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
21 TypeAliasId, TypeParamId, UnionId, VariantId, 23 TypeAliasId, TypeParamId, UnionId, VariantId,
22}; 24};
23use hir_expand::name::Name; 25use hir_expand::{name::Name, ExpandResult};
24use la_arena::ArenaMap; 26use la_arena::ArenaMap;
25use smallvec::SmallVec; 27use smallvec::SmallVec;
26use stdx::impl_from; 28use stdx::impl_from;
29use syntax::ast;
27 30
28use crate::{ 31use crate::{
29 db::HirDatabase, 32 db::HirDatabase,
30 dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, 33 dummy_usize_const,
31 traits::chalk::{Interner, ToChalk}, 34 mapping::ToChalk,
35 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
32 utils::{ 36 utils::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics, 37 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
34 }, 38 },
35 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 39 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
36 FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, 40 FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
37 QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, 41 QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
38 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, 42 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
39}; 43};
@@ -49,7 +53,7 @@ pub struct TyLoweringContext<'a> {
49 /// possible currently, so this should be fine for now. 53 /// possible currently, so this should be fine for now.
50 pub type_param_mode: TypeParamLoweringMode, 54 pub type_param_mode: TypeParamLoweringMode,
51 pub impl_trait_mode: ImplTraitLoweringMode, 55 pub impl_trait_mode: ImplTraitLoweringMode,
52 impl_trait_counter: std::cell::Cell<u16>, 56 impl_trait_counter: Cell<u16>,
53 /// When turning `impl Trait` into opaque types, we have to collect the 57 /// When turning `impl Trait` into opaque types, we have to collect the
54 /// bounds at the same time to get the IDs correct (without becoming too 58 /// bounds at the same time to get the IDs correct (without becoming too
55 /// complicated). I don't like using interior mutability (as for the 59 /// complicated). I don't like using interior mutability (as for the
@@ -58,16 +62,17 @@ pub struct TyLoweringContext<'a> {
58 /// we're grouping the mutable data (the counter and this field) together 62 /// we're grouping the mutable data (the counter and this field) together
59 /// with the immutable context (the references to the DB and resolver). 63 /// with the immutable context (the references to the DB and resolver).
60 /// Splitting this up would be a possible fix. 64 /// Splitting this up would be a possible fix.
61 opaque_type_data: std::cell::RefCell<Vec<ReturnTypeImplTrait>>, 65 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
66 expander: RefCell<Option<Expander>>,
62} 67}
63 68
64impl<'a> TyLoweringContext<'a> { 69impl<'a> TyLoweringContext<'a> {
65 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self { 70 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
66 let impl_trait_counter = std::cell::Cell::new(0); 71 let impl_trait_counter = Cell::new(0);
67 let impl_trait_mode = ImplTraitLoweringMode::Disallowed; 72 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
68 let type_param_mode = TypeParamLoweringMode::Placeholder; 73 let type_param_mode = TypeParamLoweringMode::Placeholder;
69 let in_binders = DebruijnIndex::INNERMOST; 74 let in_binders = DebruijnIndex::INNERMOST;
70 let opaque_type_data = std::cell::RefCell::new(Vec::new()); 75 let opaque_type_data = RefCell::new(Vec::new());
71 Self { 76 Self {
72 db, 77 db,
73 resolver, 78 resolver,
@@ -76,6 +81,7 @@ impl<'a> TyLoweringContext<'a> {
76 impl_trait_counter, 81 impl_trait_counter,
77 type_param_mode, 82 type_param_mode,
78 opaque_type_data, 83 opaque_type_data,
84 expander: RefCell::new(None),
79 } 85 }
80 } 86 }
81 87
@@ -85,15 +91,18 @@ impl<'a> TyLoweringContext<'a> {
85 f: impl FnOnce(&TyLoweringContext) -> T, 91 f: impl FnOnce(&TyLoweringContext) -> T,
86 ) -> T { 92 ) -> T {
87 let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new()); 93 let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new());
94 let expander = self.expander.replace(None);
88 let new_ctx = Self { 95 let new_ctx = Self {
89 in_binders: debruijn, 96 in_binders: debruijn,
90 impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()), 97 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
91 opaque_type_data: std::cell::RefCell::new(opaque_ty_data_vec), 98 opaque_type_data: RefCell::new(opaque_ty_data_vec),
99 expander: RefCell::new(expander),
92 ..*self 100 ..*self
93 }; 101 };
94 let result = f(&new_ctx); 102 let result = f(&new_ctx);
95 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get()); 103 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
96 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner()); 104 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
105 self.expander.replace(new_ctx.expander.into_inner());
97 result 106 result
98 } 107 }
99 108
@@ -286,6 +295,53 @@ impl<'a> TyLoweringContext<'a> {
286 } 295 }
287 } 296 }
288 } 297 }
298 TypeRef::Macro(macro_call) => {
299 let (expander, recursion_start) = {
300 let mut expander = self.expander.borrow_mut();
301 if expander.is_some() {
302 (Some(expander), false)
303 } else {
304 if let Some(module_id) = self.resolver.module() {
305 *expander = Some(Expander::new(
306 self.db.upcast(),
307 macro_call.file_id,
308 module_id,
309 ));
310 (Some(expander), true)
311 } else {
312 (None, false)
313 }
314 }
315 };
316 let ty = if let Some(mut expander) = expander {
317 let expander_mut = expander.as_mut().unwrap();
318 let macro_call = macro_call.to_node(self.db.upcast());
319 match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
320 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
321 let ctx =
322 LowerCtx::new(self.db.upcast(), expander_mut.current_file_id());
323 let type_ref = TypeRef::from_ast(&ctx, expanded);
324
325 drop(expander);
326 let ty = self.lower_ty(&type_ref);
327
328 self.expander
329 .borrow_mut()
330 .as_mut()
331 .unwrap()
332 .exit(self.db.upcast(), mark);
333 Some(ty)
334 }
335 _ => None,
336 }
337 } else {
338 None
339 };
340 if recursion_start {
341 *self.expander.borrow_mut() = None;
342 }
343 ty.unwrap_or_else(|| TyKind::Error.intern(&Interner))
344 }
289 TypeRef::Error => TyKind::Error.intern(&Interner), 345 TypeRef::Error => TyKind::Error.intern(&Interner),
290 }; 346 };
291 (ty, res) 347 (ty, res)
@@ -358,17 +414,16 @@ impl<'a> TyLoweringContext<'a> {
358 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty); 414 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty);
359 let ty = if remaining_segments.len() == 1 { 415 let ty = if remaining_segments.len() == 1 {
360 let segment = remaining_segments.first().unwrap(); 416 let segment = remaining_segments.first().unwrap();
361 let found = associated_type_by_name_including_super_traits( 417 let found = self
362 self.db, 418 .db
363 trait_ref, 419 .trait_data(trait_ref.hir_trait_id())
364 &segment.name, 420 .associated_type_by_name(&segment.name);
365 );
366 match found { 421 match found {
367 Some((super_trait_ref, associated_ty)) => { 422 Some(associated_ty) => {
368 // FIXME handle type parameters on the segment 423 // FIXME handle type parameters on the segment
369 TyKind::Alias(AliasTy::Projection(ProjectionTy { 424 TyKind::Alias(AliasTy::Projection(ProjectionTy {
370 associated_ty_id: to_assoc_type_id(associated_ty), 425 associated_ty_id: to_assoc_type_id(associated_ty),
371 substitution: super_trait_ref.substitution, 426 substitution: trait_ref.substitution,
372 })) 427 }))
373 .intern(&Interner) 428 .intern(&Interner)
374 } 429 }
@@ -1033,6 +1088,27 @@ pub(crate) fn generic_defaults_query(
1033 defaults 1088 defaults
1034} 1089}
1035 1090
1091pub(crate) fn generic_defaults_recover(
1092 db: &dyn HirDatabase,
1093 _cycle: &[String],
1094 def: &GenericDefId,
1095) -> Arc<[Binders<Ty>]> {
1096 let generic_params = generics(db.upcast(), *def);
1097
1098 // we still need one default per parameter
1099 let defaults = generic_params
1100 .iter()
1101 .enumerate()
1102 .map(|(idx, _)| {
1103 let ty = TyKind::Error.intern(&Interner);
1104
1105 crate::make_only_type_binders(idx, ty)
1106 })
1107 .collect();
1108
1109 defaults
1110}
1111
1036fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { 1112fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1037 let data = db.function_data(def); 1113 let data = db.function_data(def);
1038 let resolver = def.resolver(db.upcast()); 1114 let resolver = def.resolver(db.upcast());