aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/type_ref.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/type_ref.rs')
-rw-r--r--crates/ra_hir_def/src/type_ref.rs34
1 files changed, 19 insertions, 15 deletions
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index 86a77b704..a5dc10eac 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -1,7 +1,7 @@
1//! HIR for references to types. Paths in these are not yet resolved. They can 1//! HIR for references to types. Paths in these are not yet resolved. They can
2//! be directly created from an ast::TypeRef, without further queries. 2//! be directly created from an ast::TypeRef, without further queries.
3 3
4use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner}; 4use ra_syntax::ast::{self};
5 5
6use crate::{body::LowerCtx, path::Path}; 6use crate::{body::LowerCtx, path::Path};
7 7
@@ -63,7 +63,7 @@ pub enum TypeRef {
63 Array(Box<TypeRef> /*, Expr*/), 63 Array(Box<TypeRef> /*, Expr*/),
64 Slice(Box<TypeRef>), 64 Slice(Box<TypeRef>),
65 /// A fn pointer. Last element of the vector is the return type. 65 /// A fn pointer. Last element of the vector is the return type.
66 Fn(Vec<TypeRef>), 66 Fn(Vec<TypeRef>, bool /*varargs*/),
67 // For 67 // For
68 ImplTrait(Vec<TypeBound>), 68 ImplTrait(Vec<TypeBound>),
69 DynTrait(Vec<TypeBound>), 69 DynTrait(Vec<TypeBound>),
@@ -82,7 +82,7 @@ impl TypeRef {
82 /// Converts an `ast::TypeRef` to a `hir::TypeRef`. 82 /// Converts an `ast::TypeRef` to a `hir::TypeRef`.
83 pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeRef) -> Self { 83 pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeRef) -> Self {
84 match node { 84 match node {
85 ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), 85 ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(&ctx, inner.ty()),
86 ast::TypeRef::TupleType(inner) => { 86 ast::TypeRef::TupleType(inner) => {
87 TypeRef::Tuple(inner.fields().map(|it| TypeRef::from_ast(ctx, it)).collect()) 87 TypeRef::Tuple(inner.fields().map(|it| TypeRef::from_ast(ctx, it)).collect())
88 } 88 }
@@ -96,18 +96,18 @@ impl TypeRef {
96 .unwrap_or(TypeRef::Error) 96 .unwrap_or(TypeRef::Error)
97 } 97 }
98 ast::TypeRef::PointerType(inner) => { 98 ast::TypeRef::PointerType(inner) => {
99 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref()); 99 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
100 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 100 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
101 TypeRef::RawPtr(Box::new(inner_ty), mutability) 101 TypeRef::RawPtr(Box::new(inner_ty), mutability)
102 } 102 }
103 ast::TypeRef::ArrayType(inner) => { 103 ast::TypeRef::ArrayType(inner) => {
104 TypeRef::Array(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref()))) 104 TypeRef::Array(Box::new(TypeRef::from_ast_opt(&ctx, inner.ty())))
105 } 105 }
106 ast::TypeRef::SliceType(inner) => { 106 ast::TypeRef::SliceType(inner) => {
107 TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref()))) 107 TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.ty())))
108 } 108 }
109 ast::TypeRef::ReferenceType(inner) => { 109 ast::TypeRef::ReferenceType(inner) => {
110 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref()); 110 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
111 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 111 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
112 TypeRef::Reference(Box::new(inner_ty), mutability) 112 TypeRef::Reference(Box::new(inner_ty), mutability)
113 } 113 }
@@ -115,22 +115,24 @@ impl TypeRef {
115 ast::TypeRef::FnPointerType(inner) => { 115 ast::TypeRef::FnPointerType(inner) => {
116 let ret_ty = inner 116 let ret_ty = inner
117 .ret_type() 117 .ret_type()
118 .and_then(|rt| rt.type_ref()) 118 .and_then(|rt| rt.ty())
119 .map(|it| TypeRef::from_ast(ctx, it)) 119 .map(|it| TypeRef::from_ast(ctx, it))
120 .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); 120 .unwrap_or_else(|| TypeRef::Tuple(Vec::new()));
121 let mut is_varargs = false;
121 let mut params = if let Some(pl) = inner.param_list() { 122 let mut params = if let Some(pl) = inner.param_list() {
122 pl.params() 123 if let Some(param) = pl.params().last() {
123 .map(|p| p.ascribed_type()) 124 is_varargs = param.dotdotdot_token().is_some();
124 .map(|it| TypeRef::from_ast_opt(&ctx, it)) 125 }
125 .collect() 126
127 pl.params().map(|p| p.ty()).map(|it| TypeRef::from_ast_opt(&ctx, it)).collect()
126 } else { 128 } else {
127 Vec::new() 129 Vec::new()
128 }; 130 };
129 params.push(ret_ty); 131 params.push(ret_ty);
130 TypeRef::Fn(params) 132 TypeRef::Fn(params, is_varargs)
131 } 133 }
132 // for types are close enough for our purposes to the inner type for now... 134 // for types are close enough for our purposes to the inner type for now...
133 ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), 135 ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.ty()),
134 ast::TypeRef::ImplTraitType(inner) => { 136 ast::TypeRef::ImplTraitType(inner) => {
135 TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) 137 TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
136 } 138 }
@@ -158,7 +160,9 @@ impl TypeRef {
158 fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) { 160 fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
159 f(type_ref); 161 f(type_ref);
160 match type_ref { 162 match type_ref {
161 TypeRef::Fn(types) | TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)), 163 TypeRef::Fn(types, _) | TypeRef::Tuple(types) => {
164 types.iter().for_each(|t| go(t, f))
165 }
162 TypeRef::RawPtr(type_ref, _) 166 TypeRef::RawPtr(type_ref, _)
163 | TypeRef::Reference(type_ref, _) 167 | TypeRef::Reference(type_ref, _)
164 | TypeRef::Array(type_ref) 168 | TypeRef::Array(type_ref)