aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-03-17 18:37:09 +0000
committerFlorian Diebold <[email protected]>2019-03-21 21:17:00 +0000
commit8a5fbf471305894094726834f7701747fce9c961 (patch)
treed210d1a25099ca381bac2f0f2f3247fbd69b366d
parent7a8ba535422a4e3d2b649acde75b5c400ef5e7c6 (diff)
Remove the old variants replaced by Ty::Apply
-rw-r--r--crates/ra_assists/src/fill_match_arms.rs14
-rw-r--r--crates/ra_assists/src/fill_struct_fields.rs6
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/ty.rs238
-rw-r--r--crates/ra_hir/src/ty/infer.rs264
-rw-r--r--crates/ra_hir/src/ty/lower.rs38
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs11
-rw-r--r--crates/ra_hir/src/ty/op.rs33
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs27
-rw-r--r--crates/ra_ide_api/src/completion/complete_struct_literal.rs6
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs14
-rw-r--r--crates/ra_ide_api/src/hover.rs17
12 files changed, 266 insertions, 404 deletions
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs
index 6a22b0af5..da67ab667 100644
--- a/crates/ra_assists/src/fill_match_arms.rs
+++ b/crates/ra_assists/src/fill_match_arms.rs
@@ -1,7 +1,7 @@
1use std::fmt::Write; 1use std::fmt::Write;
2 2
3use hir::{ 3use hir::{
4 AdtDef, Ty, FieldSource, source_binder, 4 AdtDef, FieldSource, source_binder,
5 db::HirDatabase, 5 db::HirDatabase,
6}; 6};
7use ra_syntax::ast::{self, AstNode}; 7use ra_syntax::ast::{self, AstNode};
@@ -26,14 +26,10 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As
26 let source_map = function.body_source_map(ctx.db); 26 let source_map = function.body_source_map(ctx.db);
27 let node_expr = source_map.node_expr(expr)?; 27 let node_expr = source_map.node_expr(expr)?;
28 let match_expr_ty = infer_result[node_expr].clone(); 28 let match_expr_ty = infer_result[node_expr].clone();
29 let enum_def = match match_expr_ty { 29 let enum_def = match_expr_ty.autoderef(ctx.db).find_map(|ty| match ty.as_adt() {
30 Ty::Adt { def_id: AdtDef::Enum(e), .. } => e, 30 Some((AdtDef::Enum(e), _)) => Some(e),
31 Ty::Ref(adt, _) => match *adt { 31 _ => None,
32 Ty::Adt { def_id: AdtDef::Enum(e), .. } => e, 32 })?;
33 _ => return None,
34 },
35 _ => return None,
36 };
37 let enum_name = enum_def.name(ctx.db)?; 33 let enum_name = enum_def.name(ctx.db)?;
38 let db = ctx.db; 34 let db = ctx.db;
39 35
diff --git a/crates/ra_assists/src/fill_struct_fields.rs b/crates/ra_assists/src/fill_struct_fields.rs
index 6e61a58fc..c7790dc72 100644
--- a/crates/ra_assists/src/fill_struct_fields.rs
+++ b/crates/ra_assists/src/fill_struct_fields.rs
@@ -1,6 +1,6 @@
1use std::fmt::Write; 1use std::fmt::Write;
2 2
3use hir::{AdtDef, Ty, db::HirDatabase, source_binder::function_from_child_node}; 3use hir::{AdtDef, db::HirDatabase, source_binder::function_from_child_node};
4 4
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::ast::{self, AstNode};
6 6
@@ -60,8 +60,8 @@ where
60 let source_map = function.body_source_map(self.ctx.db); 60 let source_map = function.body_source_map(self.ctx.db);
61 let node_expr = source_map.node_expr(self.struct_lit.into())?; 61 let node_expr = source_map.node_expr(self.struct_lit.into())?;
62 let struct_lit_ty = infer_result[node_expr].clone(); 62 let struct_lit_ty = infer_result[node_expr].clone();
63 let struct_def = match struct_lit_ty { 63 let struct_def = match struct_lit_ty.as_adt() {
64 Ty::Adt { def_id: AdtDef::Struct(s), .. } => s, 64 Some((AdtDef::Struct(s), _)) => s,
65 _ => return None, 65 _ => return None,
66 }; 66 };
67 self.struct_fields = struct_def 67 self.struct_fields = struct_def
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 75c977d32..6219402d4 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -53,7 +53,7 @@ pub use self::{
53 name::Name, 53 name::Name,
54 ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner}, 54 ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner},
55 nameres::{PerNs, Namespace}, 55 nameres::{PerNs, Namespace},
56 ty::{Ty, Substs, display::HirDisplay}, 56 ty::{Ty, ApplicationTy, TypeName, Substs, display::HirDisplay},
57 impl_block::{ImplBlock, ImplItem}, 57 impl_block::{ImplBlock, ImplItem},
58 docs::{Docs, Documentation}, 58 docs::{Docs, Documentation},
59 adt::AdtDef, 59 adt::AdtDef,
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index e63775f03..0bb716569 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -20,7 +20,7 @@ pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, ca
20pub(crate) use infer::{infer, InferenceResult, InferTy}; 20pub(crate) use infer::{infer, InferenceResult, InferTy};
21use display::{HirDisplay, HirFormatter}; 21use display::{HirDisplay, HirFormatter};
22 22
23#[derive(Copy, Clone, PartialEq, Eq, Debug)] 23#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
24pub enum TypeName { 24pub enum TypeName {
25 /// The primitive boolean type. Written as `bool`. 25 /// The primitive boolean type. Written as `bool`.
26 Bool, 26 Bool,
@@ -96,80 +96,11 @@ pub struct ApplicationTy {
96/// This should be cheap to clone. 96/// This should be cheap to clone.
97#[derive(Clone, PartialEq, Eq, Debug)] 97#[derive(Clone, PartialEq, Eq, Debug)]
98pub enum Ty { 98pub enum Ty {
99 /// A nominal type with (maybe 0) type parameters. This might be a primitive
100 /// type like `bool`, a struct, tuple, function pointer, reference or
101 /// several other things.
99 Apply(ApplicationTy), 102 Apply(ApplicationTy),
100 103
101 /// The primitive boolean type. Written as `bool`.
102 Bool,
103
104 /// The primitive character type; holds a Unicode scalar value
105 /// (a non-surrogate code point). Written as `char`.
106 Char,
107
108 /// A primitive integer type. For example, `i32`.
109 Int(primitive::UncertainIntTy),
110
111 /// A primitive floating-point type. For example, `f64`.
112 Float(primitive::UncertainFloatTy),
113
114 /// Structures, enumerations and unions.
115 Adt {
116 /// The definition of the struct/enum.
117 def_id: AdtDef,
118 /// Substitutions for the generic parameters of the type.
119 substs: Substs,
120 },
121
122 /// The pointee of a string slice. Written as `str`.
123 Str,
124
125 /// The pointee of an array slice. Written as `[T]`.
126 Slice(Arc<Ty>),
127
128 /// An array with the given length. Written as `[T; n]`.
129 Array(Arc<Ty>),
130
131 /// A raw pointer. Written as `*mut T` or `*const T`
132 RawPtr(Arc<Ty>, Mutability),
133
134 /// A reference; a pointer with an associated lifetime. Written as
135 /// `&'a mut T` or `&'a T`.
136 Ref(Arc<Ty>, Mutability),
137
138 /// The anonymous type of a function declaration/definition. Each
139 /// function has a unique type, which is output (for a function
140 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
141 ///
142 /// This includes tuple struct / enum variant constructors as well.
143 ///
144 /// For example the type of `bar` here:
145 ///
146 /// ```rust
147 /// fn foo() -> i32 { 1 }
148 /// let bar = foo; // bar: fn() -> i32 {foo}
149 /// ```
150 FnDef {
151 /// The definition of the function / constructor.
152 def: CallableDef,
153 /// Substitutions for the generic parameters of the type
154 substs: Substs,
155 },
156
157 /// A pointer to a function. Written as `fn() -> i32`.
158 ///
159 /// For example the type of `bar` here:
160 ///
161 /// ```rust
162 /// fn foo() -> i32 { 1 }
163 /// let bar: fn() -> i32 = foo;
164 /// ```
165 FnPtr(Substs),
166
167 /// The never type `!`.
168 Never,
169
170 /// A tuple type. For example, `(i32, bool)`.
171 Tuple(Substs),
172
173 /// A type parameter; for example, `T` in `fn f<T>(x: T) {} 104 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
174 Param { 105 Param {
175 /// The index of the parameter (starting with parameters from the 106 /// The index of the parameter (starting with parameters from the
@@ -200,6 +131,10 @@ impl Substs {
200 Substs(Arc::new([])) 131 Substs(Arc::new([]))
201 } 132 }
202 133
134 pub fn single(ty: Ty) -> Substs {
135 Substs(Arc::new([ty]))
136 }
137
203 pub fn iter(&self) -> impl Iterator<Item = &Ty> { 138 pub fn iter(&self) -> impl Iterator<Item = &Ty> {
204 self.0.iter() 139 self.0.iter()
205 } 140 }
@@ -256,6 +191,12 @@ impl FnSig {
256} 191}
257 192
258impl Ty { 193impl Ty {
194 pub fn simple(name: TypeName) -> Ty {
195 Ty::Apply(ApplicationTy { name, parameters: Substs::empty() })
196 }
197 pub fn apply_one(name: TypeName, param: Ty) -> Ty {
198 Ty::Apply(ApplicationTy { name, parameters: Substs::single(param) })
199 }
259 pub fn apply(name: TypeName, parameters: Substs) -> Ty { 200 pub fn apply(name: TypeName, parameters: Substs) -> Ty {
260 Ty::Apply(ApplicationTy { name, parameters }) 201 Ty::Apply(ApplicationTy { name, parameters })
261 } 202 }
@@ -270,38 +211,7 @@ impl Ty {
270 t.walk(f); 211 t.walk(f);
271 } 212 }
272 } 213 }
273 Ty::Slice(t) | Ty::Array(t) => t.walk(f), 214 Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {}
274 Ty::RawPtr(t, _) => t.walk(f),
275 Ty::Ref(t, _) => t.walk(f),
276 Ty::Tuple(ts) => {
277 for t in ts.iter() {
278 t.walk(f);
279 }
280 }
281 Ty::FnPtr(sig) => {
282 for t in sig.iter() {
283 t.walk(f);
284 }
285 }
286 Ty::FnDef { substs, .. } => {
287 for t in substs.0.iter() {
288 t.walk(f);
289 }
290 }
291 Ty::Adt { substs, .. } => {
292 for t in substs.0.iter() {
293 t.walk(f);
294 }
295 }
296 Ty::Bool
297 | Ty::Char
298 | Ty::Int(_)
299 | Ty::Float(_)
300 | Ty::Str
301 | Ty::Never
302 | Ty::Param { .. }
303 | Ty::Infer(_)
304 | Ty::Unknown => {}
305 } 215 }
306 f(self); 216 f(self);
307 } 217 }
@@ -311,30 +221,7 @@ impl Ty {
311 Ty::Apply(a_ty) => { 221 Ty::Apply(a_ty) => {
312 a_ty.parameters.walk_mut(f); 222 a_ty.parameters.walk_mut(f);
313 } 223 }
314 Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f), 224 Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {}
315 Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f),
316 Ty::Ref(t, _) => Arc::make_mut(t).walk_mut(f),
317 Ty::Tuple(ts) => {
318 ts.walk_mut(f);
319 }
320 Ty::FnPtr(sig) => {
321 sig.walk_mut(f);
322 }
323 Ty::FnDef { substs, .. } => {
324 substs.walk_mut(f);
325 }
326 Ty::Adt { substs, .. } => {
327 substs.walk_mut(f);
328 }
329 Ty::Bool
330 | Ty::Char
331 | Ty::Int(_)
332 | Ty::Float(_)
333 | Ty::Str
334 | Ty::Never
335 | Ty::Param { .. }
336 | Ty::Infer(_)
337 | Ty::Unknown => {}
338 } 225 }
339 f(self); 226 f(self);
340 } 227 }
@@ -347,6 +234,31 @@ impl Ty {
347 self 234 self
348 } 235 }
349 236
237 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
238 match self {
239 Ty::Apply(ApplicationTy { name: TypeName::Ref(mutability), parameters }) => {
240 Some((parameters.as_single(), *mutability))
241 }
242 _ => None,
243 }
244 }
245
246 pub fn as_adt(&self) -> Option<(AdtDef, &Substs)> {
247 match self {
248 Ty::Apply(ApplicationTy { name: TypeName::Adt(adt_def), parameters }) => {
249 Some((*adt_def, parameters))
250 }
251 _ => None,
252 }
253 }
254
255 pub fn as_tuple(&self) -> Option<&Substs> {
256 match self {
257 Ty::Apply(ApplicationTy { name: TypeName::Tuple, parameters }) => Some(parameters),
258 _ => None,
259 }
260 }
261
350 fn builtin_deref(&self) -> Option<Ty> { 262 fn builtin_deref(&self) -> Option<Ty> {
351 match self { 263 match self {
352 Ty::Apply(a_ty) => match a_ty.name { 264 Ty::Apply(a_ty) => match a_ty.name {
@@ -354,8 +266,6 @@ impl Ty {
354 TypeName::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), 266 TypeName::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
355 _ => None, 267 _ => None,
356 }, 268 },
357 Ty::Ref(t, _) => Some(Ty::clone(t)),
358 Ty::RawPtr(t, _) => Some(Ty::clone(t)),
359 _ => None, 269 _ => None,
360 } 270 }
361 } 271 }
@@ -369,8 +279,6 @@ impl Ty {
369 Ty::Apply(ApplicationTy { name, .. }) => { 279 Ty::Apply(ApplicationTy { name, .. }) => {
370 Ty::Apply(ApplicationTy { name, parameters: substs }) 280 Ty::Apply(ApplicationTy { name, parameters: substs })
371 } 281 }
372 Ty::Adt { def_id, .. } => Ty::Adt { def_id, substs },
373 Ty::FnDef { def, .. } => Ty::FnDef { def, substs },
374 _ => self, 282 _ => self,
375 } 283 }
376 } 284 }
@@ -396,7 +304,6 @@ impl Ty {
396 fn substs(&self) -> Option<Substs> { 304 fn substs(&self) -> Option<Substs> {
397 match self { 305 match self {
398 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 306 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()),
399 Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()),
400 _ => None, 307 _ => None,
401 } 308 }
402 } 309 }
@@ -487,69 +394,6 @@ impl HirDisplay for Ty {
487 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 394 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
488 match self { 395 match self {
489 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, 396 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
490 Ty::Bool => write!(f, "bool")?,
491 Ty::Char => write!(f, "char")?,
492 Ty::Int(t) => write!(f, "{}", t)?,
493 Ty::Float(t) => write!(f, "{}", t)?,
494 Ty::Str => write!(f, "str")?,
495 Ty::Slice(t) | Ty::Array(t) => {
496 write!(f, "[{}]", t.display(f.db))?;
497 }
498 Ty::RawPtr(t, m) => {
499 write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
500 }
501 Ty::Ref(t, m) => {
502 write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
503 }
504 Ty::Never => write!(f, "!")?,
505 Ty::Tuple(ts) => {
506 if ts.0.len() == 1 {
507 write!(f, "({},)", ts.0[0].display(f.db))?;
508 } else {
509 write!(f, "(")?;
510 f.write_joined(&*ts.0, ", ")?;
511 write!(f, ")")?;
512 }
513 }
514 Ty::FnPtr(sig) => {
515 let sig = FnSig::from_fn_ptr_substs(sig);
516 write!(f, "fn(")?;
517 f.write_joined(sig.params(), ", ")?;
518 write!(f, ") -> {}", sig.ret().display(f.db))?;
519 }
520 Ty::FnDef { def, substs, .. } => {
521 let sig = f.db.callable_item_signature(*def);
522 let name = match def {
523 CallableDef::Function(ff) => ff.name(f.db),
524 CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing),
525 CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing),
526 };
527 match def {
528 CallableDef::Function(_) => write!(f, "fn {}", name)?,
529 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?,
530 }
531 if substs.0.len() > 0 {
532 write!(f, "<")?;
533 f.write_joined(&*substs.0, ", ")?;
534 write!(f, ">")?;
535 }
536 write!(f, "(")?;
537 f.write_joined(sig.params(), ", ")?;
538 write!(f, ") -> {}", sig.ret().display(f.db))?;
539 }
540 Ty::Adt { def_id, substs, .. } => {
541 let name = match def_id {
542 AdtDef::Struct(s) => s.name(f.db),
543 AdtDef::Enum(e) => e.name(f.db),
544 }
545 .unwrap_or_else(Name::missing);
546 write!(f, "{}", name)?;
547 if substs.0.len() > 0 {
548 write!(f, "<")?;
549 f.write_joined(&*substs.0, ", ")?;
550 write!(f, ">")?;
551 }
552 }
553 Ty::Param { name, .. } => write!(f, "{}", name)?, 397 Ty::Param { name, .. } => write!(f, "{}", name)?,
554 Ty::Unknown => write!(f, "{{unknown}}")?, 398 Ty::Unknown => write!(f, "{{unknown}}")?,
555 Ty::Infer(..) => write!(f, "_")?, 399 Ty::Infer(..) => write!(f, "_")?,
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 69af8fb92..0dafd8cbd 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -38,7 +38,7 @@ use crate::{
38 resolve::{Resolver, Resolution}, 38 resolve::{Resolver, Resolution},
39 nameres::Namespace 39 nameres::Namespace
40}; 40};
41use super::{Ty, TypableDef, Substs, primitive, op, FnSig}; 41use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeName};
42 42
43/// The entry point of type inference. 43/// The entry point of type inference.
44pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { 44pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
@@ -237,28 +237,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
237 match (&*ty1, &*ty2) { 237 match (&*ty1, &*ty2) {
238 (Ty::Unknown, ..) => true, 238 (Ty::Unknown, ..) => true,
239 (.., Ty::Unknown) => true, 239 (.., Ty::Unknown) => true,
240 (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) { 240 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.name == a_ty2.name => {
241 (primitive::UncertainIntTy::Unknown, _) 241 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1)
242 | (_, primitive::UncertainIntTy::Unknown) => true,
243 _ => t1 == t2,
244 },
245 (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) {
246 (primitive::UncertainFloatTy::Unknown, _)
247 | (_, primitive::UncertainFloatTy::Unknown) => true,
248 _ => t1 == t2,
249 },
250 (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2,
251 (
252 Ty::Adt { def_id: def_id1, substs: substs1, .. },
253 Ty::Adt { def_id: def_id2, substs: substs2, .. },
254 ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2, depth + 1),
255 (Ty::Slice(t1), Ty::Slice(t2)) => self.unify_inner(t1, t2, depth + 1),
256 (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => {
257 self.unify_inner(t1, t2, depth + 1)
258 } 242 }
259 (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify_inner(t1, t2, depth + 1),
260 (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) => self.unify_substs(sig1, sig2, depth + 1),
261 (Ty::Tuple(ts1), Ty::Tuple(ts2)) => self.unify_substs(ts1, ts2, depth + 1),
262 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) 243 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2)))
263 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) 244 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2)))
264 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { 245 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => {
@@ -296,8 +277,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
296 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 277 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
297 match ty { 278 match ty {
298 Ty::Unknown => self.new_type_var(), 279 Ty::Unknown => self.new_type_var(),
299 Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(), 280 Ty::Apply(ApplicationTy {
300 Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(), 281 name: TypeName::Int(primitive::UncertainIntTy::Unknown),
282 ..
283 }) => self.new_integer_var(),
284 Ty::Apply(ApplicationTy {
285 name: TypeName::Float(primitive::UncertainFloatTy::Unknown),
286 ..
287 }) => self.new_float_var(),
301 _ => ty, 288 _ => ty,
302 } 289 }
303 } 290 }
@@ -608,12 +595,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
608 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, 595 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
609 }; 596 };
610 if is_non_ref_pat { 597 if is_non_ref_pat {
611 while let Ty::Ref(inner, mutability) = expected { 598 while let Some((inner, mutability)) = expected.as_reference() {
612 expected = inner; 599 expected = inner;
613 default_bm = match default_bm { 600 default_bm = match default_bm {
614 BindingMode::Move => BindingMode::Ref(*mutability), 601 BindingMode::Move => BindingMode::Ref(mutability),
615 BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), 602 BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared),
616 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(*mutability), 603 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability),
617 } 604 }
618 } 605 }
619 } else if let Pat::Ref { .. } = &body[pat] { 606 } else if let Pat::Ref { .. } = &body[pat] {
@@ -629,8 +616,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
629 616
630 let ty = match &body[pat] { 617 let ty = match &body[pat] {
631 Pat::Tuple(ref args) => { 618 Pat::Tuple(ref args) => {
632 let expectations = match *expected { 619 let expectations = match expected.as_tuple() {
633 Ty::Tuple(ref tuple_args) => &*tuple_args.0, 620 Some(parameters) => &*parameters.0,
634 _ => &[], 621 _ => &[],
635 }; 622 };
636 let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); 623 let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown));
@@ -642,20 +629,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
642 .collect::<Vec<_>>() 629 .collect::<Vec<_>>()
643 .into(); 630 .into();
644 631
645 Ty::Tuple(Substs(inner_tys)) 632 Ty::apply(TypeName::Tuple, Substs(inner_tys))
646 } 633 }
647 Pat::Ref { pat, mutability } => { 634 Pat::Ref { pat, mutability } => {
648 let expectation = match *expected { 635 let expectation = match expected.as_reference() {
649 Ty::Ref(ref sub_ty, exp_mut) => { 636 Some((inner_ty, exp_mut)) => {
650 if *mutability != exp_mut { 637 if *mutability != exp_mut {
651 // TODO: emit type error? 638 // TODO: emit type error?
652 } 639 }
653 &**sub_ty 640 inner_ty
654 } 641 }
655 _ => &Ty::Unknown, 642 _ => &Ty::Unknown,
656 }; 643 };
657 let subty = self.infer_pat(*pat, expectation, default_bm); 644 let subty = self.infer_pat(*pat, expectation, default_bm);
658 Ty::Ref(subty.into(), *mutability) 645 Ty::apply_one(TypeName::Ref(*mutability), subty.into())
659 } 646 }
660 Pat::TupleStruct { path: ref p, args: ref subpats } => { 647 Pat::TupleStruct { path: ref p, args: ref subpats } => {
661 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) 648 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm)
@@ -682,7 +669,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
682 let inner_ty = self.insert_type_vars_shallow(inner_ty); 669 let inner_ty = self.insert_type_vars_shallow(inner_ty);
683 670
684 let bound_ty = match mode { 671 let bound_ty = match mode {
685 BindingMode::Ref(mutability) => Ty::Ref(inner_ty.clone().into(), mutability), 672 BindingMode::Ref(mutability) => {
673 Ty::apply_one(TypeName::Ref(mutability), inner_ty.clone().into())
674 }
686 BindingMode::Move => inner_ty.clone(), 675 BindingMode::Move => inner_ty.clone(),
687 }; 676 };
688 let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty); 677 let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty);
@@ -736,7 +725,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
736 Expr::Missing => Ty::Unknown, 725 Expr::Missing => Ty::Unknown,
737 Expr::If { condition, then_branch, else_branch } => { 726 Expr::If { condition, then_branch, else_branch } => {
738 // if let is desugared to match, so this is always simple if 727 // if let is desugared to match, so this is always simple if
739 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); 728 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeName::Bool)));
740 let then_ty = self.infer_expr(*then_branch, expected); 729 let then_ty = self.infer_expr(*then_branch, expected);
741 match else_branch { 730 match else_branch {
742 Some(else_branch) => { 731 Some(else_branch) => {
@@ -753,11 +742,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
753 Expr::Loop { body } => { 742 Expr::Loop { body } => {
754 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 743 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
755 // TODO handle break with value 744 // TODO handle break with value
756 Ty::Never 745 Ty::simple(TypeName::Never)
757 } 746 }
758 Expr::While { condition, body } => { 747 Expr::While { condition, body } => {
759 // while let is desugared to a match loop, so this is always simple while 748 // while let is desugared to a match loop, so this is always simple while
760 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); 749 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeName::Bool)));
761 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 750 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
762 Ty::unit() 751 Ty::unit()
763 } 752 }
@@ -787,17 +776,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
787 Expr::Call { callee, args } => { 776 Expr::Call { callee, args } => {
788 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 777 let callee_ty = self.infer_expr(*callee, &Expectation::none());
789 let (param_tys, ret_ty) = match &callee_ty { 778 let (param_tys, ret_ty) = match &callee_ty {
790 Ty::FnPtr(sig) => { 779 Ty::Apply(a_ty) => match a_ty.name {
791 let sig = FnSig::from_fn_ptr_substs(sig); 780 TypeName::FnPtr => {
792 (sig.params().to_vec(), sig.ret().clone()) 781 let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters);
793 } 782 (sig.params().to_vec(), sig.ret().clone())
794 Ty::FnDef { substs, def, .. } => { 783 }
795 let sig = self.db.callable_item_signature(*def); 784 TypeName::FnDef(def) => {
796 let ret_ty = sig.ret().clone().subst(&substs); 785 let sig = self.db.callable_item_signature(def);
797 let param_tys = 786 let ret_ty = sig.ret().clone().subst(&a_ty.parameters);
798 sig.params().iter().map(|ty| ty.clone().subst(&substs)).collect(); 787 let param_tys = sig
799 (param_tys, ret_ty) 788 .params()
800 } 789 .iter()
790 .map(|ty| ty.clone().subst(&a_ty.parameters))
791 .collect();
792 (param_tys, ret_ty)
793 }
794 _ => (Vec::new(), Ty::Unknown),
795 },
801 _ => { 796 _ => {
802 // not callable 797 // not callable
803 // TODO report an error? 798 // TODO report an error?
@@ -828,32 +823,43 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
828 let method_ty = method_ty.apply_substs(substs); 823 let method_ty = method_ty.apply_substs(substs);
829 let method_ty = self.insert_type_vars(method_ty); 824 let method_ty = self.insert_type_vars(method_ty);
830 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { 825 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
831 Ty::FnPtr(sig) => { 826 Ty::Apply(a_ty) => match a_ty.name {
832 let sig = FnSig::from_fn_ptr_substs(sig); 827 TypeName::FnPtr => {
833 if !sig.params().is_empty() { 828 let sig = FnSig::from_fn_ptr_substs(&a_ty.parameters);
834 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) 829 if !sig.params().is_empty() {
835 } else { 830 (
836 (Ty::Unknown, Vec::new(), sig.ret().clone()) 831 sig.params()[0].clone(),
832 sig.params()[1..].to_vec(),
833 sig.ret().clone(),
834 )
835 } else {
836 (Ty::Unknown, Vec::new(), sig.ret().clone())
837 }
837 } 838 }
838 } 839 TypeName::FnDef(def) => {
839 Ty::FnDef { substs, def, .. } => { 840 let sig = self.db.callable_item_signature(def);
840 let sig = self.db.callable_item_signature(*def); 841 let ret_ty = sig.ret().clone().subst(&a_ty.parameters);
841 let ret_ty = sig.ret().clone().subst(&substs); 842
842 843 if !sig.params().is_empty() {
843 if !sig.params().is_empty() { 844 let mut params_iter = sig
844 let mut params_iter = 845 .params()
845 sig.params().iter().map(|ty| ty.clone().subst(&substs)); 846 .iter()
846 let receiver_ty = params_iter.next().unwrap(); 847 .map(|ty| ty.clone().subst(&a_ty.parameters));
847 (receiver_ty, params_iter.collect(), ret_ty) 848 let receiver_ty = params_iter.next().unwrap();
848 } else { 849 (receiver_ty, params_iter.collect(), ret_ty)
849 (Ty::Unknown, Vec::new(), ret_ty) 850 } else {
851 (Ty::Unknown, Vec::new(), ret_ty)
852 }
850 } 853 }
851 } 854 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
855 },
852 _ => (Ty::Unknown, Vec::new(), Ty::Unknown), 856 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
853 }; 857 };
854 // Apply autoref so the below unification works correctly 858 // Apply autoref so the below unification works correctly
855 let actual_receiver_ty = match expected_receiver_ty { 859 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
856 Ty::Ref(_, mutability) => Ty::Ref(Arc::new(derefed_receiver_ty), mutability), 860 Some((_, mutability)) => {
861 Ty::apply_one(TypeName::Ref(mutability), derefed_receiver_ty)
862 }
857 _ => derefed_receiver_ty, 863 _ => derefed_receiver_ty,
858 }; 864 };
859 self.unify(&expected_receiver_ty, &actual_receiver_ty); 865 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -877,7 +883,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
877 let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default()); 883 let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default());
878 } 884 }
879 if let Some(guard_expr) = arm.guard { 885 if let Some(guard_expr) = arm.guard {
880 self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool)); 886 self.infer_expr(
887 guard_expr,
888 &Expectation::has_type(Ty::simple(TypeName::Bool)),
889 );
881 } 890 }
882 self.infer_expr(arm.expr, &expected); 891 self.infer_expr(arm.expr, &expected);
883 } 892 }
@@ -889,19 +898,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
889 let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); 898 let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr);
890 self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 899 self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
891 } 900 }
892 Expr::Continue => Ty::Never, 901 Expr::Continue => Ty::simple(TypeName::Never),
893 Expr::Break { expr } => { 902 Expr::Break { expr } => {
894 if let Some(expr) = expr { 903 if let Some(expr) = expr {
895 // TODO handle break with value 904 // TODO handle break with value
896 self.infer_expr(*expr, &Expectation::none()); 905 self.infer_expr(*expr, &Expectation::none());
897 } 906 }
898 Ty::Never 907 Ty::simple(TypeName::Never)
899 } 908 }
900 Expr::Return { expr } => { 909 Expr::Return { expr } => {
901 if let Some(expr) = expr { 910 if let Some(expr) = expr {
902 self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); 911 self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()));
903 } 912 }
904 Ty::Never 913 Ty::simple(TypeName::Never)
905 } 914 }
906 Expr::StructLit { path, fields, spread } => { 915 Expr::StructLit { path, fields, spread } => {
907 let (ty, def_id) = self.resolve_variant(path.as_ref()); 916 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -923,16 +932,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
923 let ty = receiver_ty 932 let ty = receiver_ty
924 .autoderef(self.db) 933 .autoderef(self.db)
925 .find_map(|derefed_ty| match derefed_ty { 934 .find_map(|derefed_ty| match derefed_ty {
926 Ty::Tuple(fields) => { 935 Ty::Apply(a_ty) => match a_ty.name {
927 let i = name.to_string().parse::<usize>().ok(); 936 TypeName::Tuple => {
928 i.and_then(|i| fields.0.get(i).cloned()) 937 let i = name.to_string().parse::<usize>().ok();
929 } 938 i.and_then(|i| a_ty.parameters.0.get(i).cloned())
930 Ty::Adt { def_id: AdtDef::Struct(s), ref substs, .. } => { 939 }
931 s.field(self.db, name).map(|field| { 940 TypeName::Adt(AdtDef::Struct(s)) => {
932 self.write_field_resolution(tgt_expr, field); 941 s.field(self.db, name).map(|field| {
933 field.ty(self.db).subst(substs) 942 self.write_field_resolution(tgt_expr, field);
934 }) 943 field.ty(self.db).subst(&a_ty.parameters)
935 } 944 })
945 }
946 _ => None,
947 },
936 _ => None, 948 _ => None,
937 }) 949 })
938 .unwrap_or(Ty::Unknown); 950 .unwrap_or(Ty::Unknown);
@@ -949,18 +961,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
949 cast_ty 961 cast_ty
950 } 962 }
951 Expr::Ref { expr, mutability } => { 963 Expr::Ref { expr, mutability } => {
952 let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty { 964 let expectation =
953 if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared { 965 if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() {
954 // TODO: throw type error - expected mut reference but found shared ref, 966 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared {
955 // which cannot be coerced 967 // TODO: throw type error - expected mut reference but found shared ref,
956 } 968 // which cannot be coerced
957 Expectation::has_type((**subty).clone()) 969 }
958 } else { 970 Expectation::has_type(Ty::clone(exp_inner))
959 Expectation::none() 971 } else {
960 }; 972 Expectation::none()
973 };
961 // TODO reference coercions etc. 974 // TODO reference coercions etc.
962 let inner_ty = self.infer_expr(*expr, &expectation); 975 let inner_ty = self.infer_expr(*expr, &expectation);
963 Ty::Ref(Arc::new(inner_ty), *mutability) 976 Ty::apply_one(TypeName::Ref(*mutability), inner_ty)
964 } 977 }
965 Expr::UnaryOp { expr, op } => { 978 Expr::UnaryOp { expr, op } => {
966 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 979 let inner_ty = self.infer_expr(*expr, &Expectation::none());
@@ -974,19 +987,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
974 } 987 }
975 } 988 }
976 UnaryOp::Neg => { 989 UnaryOp::Neg => {
977 match inner_ty { 990 match &inner_ty {
978 Ty::Int(primitive::UncertainIntTy::Unknown) 991 Ty::Apply(a_ty) => match a_ty.name {
979 | Ty::Int(primitive::UncertainIntTy::Signed(..)) 992 TypeName::Int(primitive::UncertainIntTy::Unknown)
980 | Ty::Infer(InferTy::IntVar(..)) 993 | TypeName::Int(primitive::UncertainIntTy::Signed(..))
981 | Ty::Infer(InferTy::FloatVar(..)) 994 | TypeName::Float(..) => inner_ty,
982 | Ty::Float(..) => inner_ty, 995 _ => Ty::Unknown,
996 },
997 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => {
998 inner_ty
999 }
983 // TODO: resolve ops::Neg trait 1000 // TODO: resolve ops::Neg trait
984 _ => Ty::Unknown, 1001 _ => Ty::Unknown,
985 } 1002 }
986 } 1003 }
987 UnaryOp::Not => { 1004 UnaryOp::Not => {
988 match inner_ty { 1005 match &inner_ty {
989 Ty::Bool | Ty::Int(_) | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 1006 Ty::Apply(a_ty) => match a_ty.name {
1007 TypeName::Bool | TypeName::Int(_) => inner_ty,
1008 _ => Ty::Unknown,
1009 },
1010 Ty::Infer(InferTy::IntVar(..)) => inner_ty,
990 // TODO: resolve ops::Not trait for inner_ty 1011 // TODO: resolve ops::Not trait for inner_ty
991 _ => Ty::Unknown, 1012 _ => Ty::Unknown,
992 } 1013 }
@@ -997,7 +1018,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
997 Some(op) => { 1018 Some(op) => {
998 let lhs_expectation = match op { 1019 let lhs_expectation = match op {
999 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { 1020 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => {
1000 Expectation::has_type(Ty::Bool) 1021 Expectation::has_type(Ty::simple(TypeName::Bool))
1001 } 1022 }
1002 _ => Expectation::none(), 1023 _ => Expectation::none(),
1003 }; 1024 };
@@ -1018,11 +1039,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1018 ty_vec.push(self.infer_expr(*arg, &Expectation::none())); 1039 ty_vec.push(self.infer_expr(*arg, &Expectation::none()));
1019 } 1040 }
1020 1041
1021 Ty::Tuple(Substs(ty_vec.into())) 1042 Ty::apply(TypeName::Tuple, Substs(ty_vec.into()))
1022 } 1043 }
1023 Expr::Array { exprs } => { 1044 Expr::Array { exprs } => {
1024 let elem_ty = match &expected.ty { 1045 let elem_ty = match &expected.ty {
1025 Ty::Slice(inner) | Ty::Array(inner) => Ty::clone(&inner), 1046 Ty::Apply(a_ty) => match a_ty.name {
1047 TypeName::Slice | TypeName::Array => {
1048 Ty::clone(&a_ty.parameters.as_single())
1049 }
1050 _ => self.new_type_var(),
1051 },
1026 _ => self.new_type_var(), 1052 _ => self.new_type_var(),
1027 }; 1053 };
1028 1054
@@ -1030,21 +1056,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1030 self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); 1056 self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
1031 } 1057 }
1032 1058
1033 Ty::Array(Arc::new(elem_ty)) 1059 Ty::apply_one(TypeName::Array, elem_ty)
1034 } 1060 }
1035 Expr::Literal(lit) => match lit { 1061 Expr::Literal(lit) => match lit {
1036 Literal::Bool(..) => Ty::Bool, 1062 Literal::Bool(..) => Ty::simple(TypeName::Bool),
1037 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared), 1063 Literal::String(..) => {
1064 Ty::apply_one(TypeName::Ref(Mutability::Shared), Ty::simple(TypeName::Str))
1065 }
1038 Literal::ByteString(..) => { 1066 Literal::ByteString(..) => {
1039 let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned( 1067 let byte_type = Ty::simple(TypeName::Int(primitive::UncertainIntTy::Unsigned(
1040 primitive::UintTy::U8, 1068 primitive::UintTy::U8,
1041 ))); 1069 )));
1042 let slice_type = Arc::new(Ty::Slice(byte_type)); 1070 let slice_type = Ty::apply_one(TypeName::Slice, byte_type);
1043 Ty::Ref(slice_type, Mutability::Shared) 1071 Ty::apply_one(TypeName::Ref(Mutability::Shared), slice_type)
1044 } 1072 }
1045 Literal::Char(..) => Ty::Char, 1073 Literal::Char(..) => Ty::simple(TypeName::Char),
1046 Literal::Int(_v, ty) => Ty::Int(*ty), 1074 Literal::Int(_v, ty) => Ty::simple(TypeName::Int(*ty)),
1047 Literal::Float(_v, ty) => Ty::Float(*ty), 1075 Literal::Float(_v, ty) => Ty::simple(TypeName::Float(*ty)),
1048 }, 1076 },
1049 }; 1077 };
1050 // use a new type variable if we got Ty::Unknown here 1078 // use a new type variable if we got Ty::Unknown here
@@ -1180,11 +1208,11 @@ impl InferTy {
1180 match self { 1208 match self {
1181 InferTy::TypeVar(..) => Ty::Unknown, 1209 InferTy::TypeVar(..) => Ty::Unknown,
1182 InferTy::IntVar(..) => { 1210 InferTy::IntVar(..) => {
1183 Ty::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32)) 1211 Ty::simple(TypeName::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32)))
1184 }
1185 InferTy::FloatVar(..) => {
1186 Ty::Float(primitive::UncertainFloatTy::Known(primitive::FloatTy::F64))
1187 } 1212 }
1213 InferTy::FloatVar(..) => Ty::simple(TypeName::Float(
1214 primitive::UncertainFloatTy::Known(primitive::FloatTy::F64),
1215 )),
1188 } 1216 }
1189 } 1217 }
1190} 1218}
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 20e6273a6..a346879d8 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -6,8 +6,6 @@
6//! 6//!
7//! This usually involves resolving names, collecting generic arguments etc. 7//! This usually involves resolving names, collecting generic arguments etc.
8 8
9use std::sync::Arc;
10
11use crate::{ 9use crate::{
12 Function, Struct, StructField, Enum, EnumVariant, Path, 10 Function, Struct, StructField, Enum, EnumVariant, Path,
13 ModuleDef, TypeAlias, 11 ModuleDef, TypeAlias,
@@ -21,40 +19,40 @@ use crate::{
21 generics::GenericParams, 19 generics::GenericParams,
22 adt::VariantDef, 20 adt::VariantDef,
23}; 21};
24use super::{Ty, primitive, FnSig, Substs}; 22use super::{Ty, primitive, FnSig, Substs, TypeName};
25 23
26impl Ty { 24impl Ty {
27 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { 25 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
28 match type_ref { 26 match type_ref {
29 TypeRef::Never => Ty::Never, 27 TypeRef::Never => Ty::simple(TypeName::Never),
30 TypeRef::Tuple(inner) => { 28 TypeRef::Tuple(inner) => {
31 let inner_tys = 29 let inner_tys =
32 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 30 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
33 Ty::Tuple(Substs(inner_tys.into())) 31 Ty::apply(TypeName::Tuple, Substs(inner_tys.into()))
34 } 32 }
35 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), 33 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path),
36 TypeRef::RawPtr(inner, mutability) => { 34 TypeRef::RawPtr(inner, mutability) => {
37 let inner_ty = Ty::from_hir(db, resolver, inner); 35 let inner_ty = Ty::from_hir(db, resolver, inner);
38 Ty::RawPtr(Arc::new(inner_ty), *mutability) 36 Ty::apply_one(TypeName::RawPtr(*mutability), inner_ty)
39 } 37 }
40 TypeRef::Array(inner) => { 38 TypeRef::Array(inner) => {
41 let inner_ty = Ty::from_hir(db, resolver, inner); 39 let inner_ty = Ty::from_hir(db, resolver, inner);
42 Ty::Array(Arc::new(inner_ty)) 40 Ty::apply_one(TypeName::Array, inner_ty)
43 } 41 }
44 TypeRef::Slice(inner) => { 42 TypeRef::Slice(inner) => {
45 let inner_ty = Ty::from_hir(db, resolver, inner); 43 let inner_ty = Ty::from_hir(db, resolver, inner);
46 Ty::Slice(Arc::new(inner_ty)) 44 Ty::apply_one(TypeName::Slice, inner_ty)
47 } 45 }
48 TypeRef::Reference(inner, mutability) => { 46 TypeRef::Reference(inner, mutability) => {
49 let inner_ty = Ty::from_hir(db, resolver, inner); 47 let inner_ty = Ty::from_hir(db, resolver, inner);
50 Ty::Ref(Arc::new(inner_ty), *mutability) 48 Ty::apply_one(TypeName::Ref(*mutability), inner_ty)
51 } 49 }
52 TypeRef::Placeholder => Ty::Unknown, 50 TypeRef::Placeholder => Ty::Unknown,
53 TypeRef::Fn(params) => { 51 TypeRef::Fn(params) => {
54 let inner_tys = 52 let inner_tys =
55 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 53 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
56 let sig = Substs(inner_tys.into()); 54 let sig = Substs(inner_tys.into());
57 Ty::FnPtr(sig) 55 Ty::apply(TypeName::FnPtr, sig)
58 } 56 }
59 TypeRef::Error => Ty::Unknown, 57 TypeRef::Error => Ty::Unknown,
60 } 58 }
@@ -64,14 +62,14 @@ impl Ty {
64 if let Some(name) = path.as_ident() { 62 if let Some(name) = path.as_ident() {
65 // TODO handle primitive type names in resolver as well? 63 // TODO handle primitive type names in resolver as well?
66 if let Some(int_ty) = primitive::UncertainIntTy::from_type_name(name) { 64 if let Some(int_ty) = primitive::UncertainIntTy::from_type_name(name) {
67 return Ty::Int(int_ty); 65 return Ty::simple(TypeName::Int(int_ty));
68 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_type_name(name) { 66 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_type_name(name) {
69 return Ty::Float(float_ty); 67 return Ty::simple(TypeName::Float(float_ty));
70 } else if let Some(known) = name.as_known_name() { 68 } else if let Some(known) = name.as_known_name() {
71 match known { 69 match known {
72 KnownName::Bool => return Ty::Bool, 70 KnownName::Bool => return Ty::simple(TypeName::Bool),
73 KnownName::Char => return Ty::Char, 71 KnownName::Char => return Ty::simple(TypeName::Char),
74 KnownName::Str => return Ty::Str, 72 KnownName::Str => return Ty::simple(TypeName::Str),
75 _ => {} 73 _ => {}
76 } 74 }
77 } 75 }
@@ -247,7 +245,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
247fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 245fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
248 let generics = def.generic_params(db); 246 let generics = def.generic_params(db);
249 let substs = make_substs(&generics); 247 let substs = make_substs(&generics);
250 Ty::FnDef { def: def.into(), substs } 248 Ty::apply(TypeName::FnDef(def.into()), substs)
251} 249}
252 250
253/// Build the declared type of a const. 251/// Build the declared type of a const.
@@ -289,7 +287,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
289 } 287 }
290 let generics = def.generic_params(db); 288 let generics = def.generic_params(db);
291 let substs = make_substs(&generics); 289 let substs = make_substs(&generics);
292 Ty::FnDef { def: def.into(), substs } 290 Ty::apply(TypeName::FnDef(def.into()), substs)
293} 291}
294 292
295fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { 293fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
@@ -317,7 +315,7 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
317 } 315 }
318 let generics = def.parent_enum(db).generic_params(db); 316 let generics = def.parent_enum(db).generic_params(db);
319 let substs = make_substs(&generics); 317 let substs = make_substs(&generics);
320 Ty::FnDef { def: def.into(), substs } 318 Ty::apply(TypeName::FnDef(def.into()), substs)
321} 319}
322 320
323fn make_substs(generics: &GenericParams) -> Substs { 321fn make_substs(generics: &GenericParams) -> Substs {
@@ -333,12 +331,12 @@ fn make_substs(generics: &GenericParams) -> Substs {
333 331
334fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 332fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
335 let generics = s.generic_params(db); 333 let generics = s.generic_params(db);
336 Ty::Adt { def_id: s.into(), substs: make_substs(&generics) } 334 Ty::apply(TypeName::Adt(s.into()), make_substs(&generics))
337} 335}
338 336
339fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { 337fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
340 let generics = s.generic_params(db); 338 let generics = s.generic_params(db);
341 Ty::Adt { def_id: s.into(), substs: make_substs(&generics) } 339 Ty::apply(TypeName::Adt(s.into()), make_substs(&generics))
342} 340}
343 341
344fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 342fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 804824868..06bfe85cd 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -10,7 +10,7 @@ use crate::{
10 HirDatabase, Module, Crate, Name, Function, Trait, 10 HirDatabase, Module, Crate, Name, Function, Trait,
11 ids::TraitId, 11 ids::TraitId,
12 impl_block::{ImplId, ImplBlock, ImplItem}, 12 impl_block::{ImplId, ImplBlock, ImplItem},
13 ty::{AdtDef, Ty}, 13 ty::{Ty, TypeName},
14 nameres::CrateModuleId, 14 nameres::CrateModuleId,
15 15
16}; 16};
@@ -18,7 +18,7 @@ use crate::{
18/// This is used as a key for indexing impls. 18/// This is used as a key for indexing impls.
19#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 19#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
20pub enum TyFingerprint { 20pub enum TyFingerprint {
21 Adt(AdtDef), // we'll also want to index impls for primitive types etc. 21 Apply(TypeName),
22} 22}
23 23
24impl TyFingerprint { 24impl TyFingerprint {
@@ -27,7 +27,7 @@ impl TyFingerprint {
27 /// `impl &S`. Hence, this will return `None` for reference types and such. 27 /// `impl &S`. Hence, this will return `None` for reference types and such.
28 fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 28 fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
29 match ty { 29 match ty {
30 Ty::Adt { def_id, .. } => Some(TyFingerprint::Adt(*def_id)), 30 Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.name)),
31 _ => None, 31 _ => None,
32 } 32 }
33 } 33 }
@@ -111,7 +111,10 @@ impl CrateImplBlocks {
111 111
112fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { 112fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> {
113 match ty { 113 match ty {
114 Ty::Adt { def_id, .. } => def_id.krate(db), 114 Ty::Apply(a_ty) => match a_ty.name {
115 TypeName::Adt(def_id) => def_id.krate(db),
116 _ => None,
117 },
115 _ => None, 118 _ => None,
116 } 119 }
117} 120}
diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs
index 8703cf236..f581004d2 100644
--- a/crates/ra_hir/src/ty/op.rs
+++ b/crates/ra_hir/src/ty/op.rs
@@ -1,5 +1,5 @@
1use crate::expr::BinaryOp; 1use crate::{ ty::ApplicationTy, expr::BinaryOp};
2use super::{Ty, InferTy}; 2use super::{Ty, TypeName, InferTy};
3 3
4pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { 4pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
5 match op { 5 match op {
@@ -10,7 +10,7 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
10 | BinaryOp::LesserEqualTest 10 | BinaryOp::LesserEqualTest
11 | BinaryOp::GreaterEqualTest 11 | BinaryOp::GreaterEqualTest
12 | BinaryOp::LesserTest 12 | BinaryOp::LesserTest
13 | BinaryOp::GreaterTest => Ty::Bool, 13 | BinaryOp::GreaterTest => Ty::simple(TypeName::Bool),
14 BinaryOp::Assignment 14 BinaryOp::Assignment
15 | BinaryOp::AddAssign 15 | BinaryOp::AddAssign
16 | BinaryOp::SubAssign 16 | BinaryOp::SubAssign
@@ -32,10 +32,11 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
32 | BinaryOp::BitwiseAnd 32 | BinaryOp::BitwiseAnd
33 | BinaryOp::BitwiseOr 33 | BinaryOp::BitwiseOr
34 | BinaryOp::BitwiseXor => match rhs_ty { 34 | BinaryOp::BitwiseXor => match rhs_ty {
35 Ty::Int(..) 35 Ty::Apply(ApplicationTy { name, .. }) => match name {
36 | Ty::Float(..) 36 TypeName::Int(..) | TypeName::Float(..) => rhs_ty,
37 | Ty::Infer(InferTy::IntVar(..)) 37 _ => Ty::Unknown,
38 | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, 38 },
39 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty,
39 _ => Ty::Unknown, 40 _ => Ty::Unknown,
40 }, 41 },
41 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, 42 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
@@ -44,9 +45,17 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
44 45
45pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 46pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
46 match op { 47 match op {
47 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, 48 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::simple(TypeName::Bool),
48 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { 49 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
49 Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, 50 Ty::Apply(ApplicationTy { name, .. }) => match name {
51 TypeName::Int(..)
52 | TypeName::Float(..)
53 | TypeName::Str
54 | TypeName::Char
55 | TypeName::Bool => lhs_ty,
56 _ => Ty::Unknown,
57 },
58 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
50 _ => Ty::Unknown, 59 _ => Ty::Unknown,
51 }, 60 },
52 BinaryOp::LesserEqualTest 61 BinaryOp::LesserEqualTest
@@ -73,7 +82,11 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
73 | BinaryOp::BitwiseAnd 82 | BinaryOp::BitwiseAnd
74 | BinaryOp::BitwiseOr 83 | BinaryOp::BitwiseOr
75 | BinaryOp::BitwiseXor => match lhs_ty { 84 | BinaryOp::BitwiseXor => match lhs_ty {
76 Ty::Int(..) | Ty::Float(..) => lhs_ty, 85 Ty::Apply(ApplicationTy { name, .. }) => match name {
86 TypeName::Int(..) | TypeName::Float(..) => lhs_ty,
87 _ => Ty::Unknown,
88 },
89 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
77 _ => Ty::Unknown, 90 _ => Ty::Unknown,
78 }, 91 },
79 _ => Ty::Unknown, 92 _ => Ty::Unknown,
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 94c66be31..dc5206a64 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -1,4 +1,4 @@
1use hir::{Ty, AdtDef}; 1use hir::{Ty, AdtDef, TypeName};
2 2
3use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
4 4
@@ -24,23 +24,20 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
24fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { 24fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
25 for receiver in receiver.autoderef(ctx.db) { 25 for receiver in receiver.autoderef(ctx.db) {
26 match receiver { 26 match receiver {
27 Ty::Adt { def_id, ref substs, .. } => { 27 Ty::Apply(a_ty) => match a_ty.name {
28 match def_id { 28 TypeName::Adt(AdtDef::Struct(s)) => {
29 AdtDef::Struct(s) => { 29 for field in s.fields(ctx.db) {
30 for field in s.fields(ctx.db) { 30 acc.add_field(ctx, field, &a_ty.parameters);
31 acc.add_field(ctx, field, substs);
32 }
33 } 31 }
34
35 // TODO unions
36 AdtDef::Enum(_) => (),
37 } 32 }
38 } 33 // TODO unions
39 Ty::Tuple(fields) => { 34 TypeName::Tuple => {
40 for (i, ty) in fields.iter().enumerate() { 35 for (i, ty) in a_ty.parameters.iter().enumerate() {
41 acc.add_pos_field(ctx, i, ty); 36 acc.add_pos_field(ctx, i, ty);
37 }
42 } 38 }
43 } 39 _ => {}
40 },
44 _ => {} 41 _ => {}
45 }; 42 };
46 } 43 }
diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
index 6bef9624e..b75526282 100644
--- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs
+++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
@@ -1,4 +1,4 @@
1use hir::{Ty, AdtDef}; 1use hir::AdtDef;
2 2
3use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
4 4
@@ -15,8 +15,8 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon
15 None => return, 15 None => return,
16 }; 16 };
17 let ty = infer_result[expr].clone(); 17 let ty = infer_result[expr].clone();
18 let (adt, substs) = match ty { 18 let (adt, substs) = match ty.as_adt() {
19 Ty::Adt { def_id, ref substs, .. } => (def_id, substs), 19 Some(res) => res,
20 _ => return, 20 _ => return,
21 }; 21 };
22 match adt { 22 match adt {
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index d4e10b69c..f94487d94 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -87,14 +87,12 @@ pub(crate) fn reference_definition(
87 87
88 if let Some(expr) = struct_lit.and_then(|lit| source_map.node_expr(lit.into())) { 88 if let Some(expr) = struct_lit.and_then(|lit| source_map.node_expr(lit.into())) {
89 let ty = infer_result[expr].clone(); 89 let ty = infer_result[expr].clone();
90 if let hir::Ty::Adt { def_id, .. } = ty { 90 if let Some((hir::AdtDef::Struct(s), _)) = ty.as_adt() {
91 if let hir::AdtDef::Struct(s) = def_id { 91 let hir_path = hir::Path::from_name_ref(name_ref);
92 let hir_path = hir::Path::from_name_ref(name_ref); 92 let hir_name = hir_path.as_ident().unwrap();
93 let hir_name = hir_path.as_ident().unwrap();
94 93
95 if let Some(field) = s.field(db, hir_name) { 94 if let Some(field) = s.field(db, hir_name) {
96 return Exact(NavigationTarget::from_field(db, field)); 95 return Exact(NavigationTarget::from_field(db, field));
97 }
98 } 96 }
99 } 97 }
100 } 98 }
@@ -124,7 +122,7 @@ pub(crate) fn reference_definition(
124 Some(Resolution::SelfType(impl_block)) => { 122 Some(Resolution::SelfType(impl_block)) => {
125 let ty = impl_block.target_ty(db); 123 let ty = impl_block.target_ty(db);
126 124
127 if let hir::Ty::Adt { def_id, .. } = ty { 125 if let Some((def_id, _)) = ty.as_adt() {
128 return Exact(NavigationTarget::from_adt_def(db, def_id)); 126 return Exact(NavigationTarget::from_adt_def(db, def_id));
129 } 127 }
130 } 128 }
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index f6a83dd93..f6443580d 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -517,23 +517,8 @@ The Some variant
517 assert_eq!("u32", &type_name); 517 assert_eq!("u32", &type_name);
518 } 518 }
519 519
520 // FIXME: improve type_of to make this work
521 #[test] 520 #[test]
522 fn test_type_of_for_expr_1() { 521 fn test_type_of_for_expr() {
523 let (analysis, range) = single_file_with_range(
524 "
525 fn main() {
526 let foo = <|>1 + foo_test<|>;
527 }
528 ",
529 );
530
531 let type_name = analysis.type_of(range).unwrap().unwrap();
532 assert_eq!("{unknown}", &type_name);
533 }
534
535 #[test]
536 fn test_type_of_for_expr_2() {
537 let (analysis, range) = single_file_with_range( 522 let (analysis, range) = single_file_with_range(
538 " 523 "
539 fn main() { 524 fn main() {