aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-02-28 18:13:37 +0000
committerLukas Wirth <[email protected]>2021-02-28 18:13:37 +0000
commita3f5491a1a312393429a44028e7496fe0a12f8c2 (patch)
tree849e144e00a29223333b24acc813306c6acb5ba2 /crates/hir_ty/src/infer
parent7c2dd85a32e320fd412a720ea5b847c66bf246ae (diff)
Inline TypeCtor into Ty
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs79
-rw-r--r--crates/hir_ty/src/infer/expr.rs238
-rw-r--r--crates/hir_ty/src/infer/pat.rs27
-rw-r--r--crates/hir_ty/src/infer/unify.rs38
4 files changed, 157 insertions, 225 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..cd5fb3252 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +7,7 @@
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability};
8use test_utils::mark; 8use test_utils::mark;
9 9
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 11
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext};
13 13
@@ -33,7 +33,7 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 33 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 34 ty1.clone()
35 } else { 35 } else {
36 if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { 36 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) {
37 mark::hit!(coerce_fn_reification); 37 mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 38 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 39 // pointers to have a chance at getting a match. See
@@ -53,12 +53,12 @@ impl<'a> InferenceContext<'a> {
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 54 match (&from_ty, to_ty) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 55 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 56 (Ty::Never, Ty::Infer(InferTy::TypeVar(tv))) => {
57 let var = self.table.new_maybe_never_type_var(); 57 let var = self.table.new_maybe_never_type_var();
58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); 58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var));
59 return true; 59 return true;
60 } 60 }
61 (ty_app!(TypeCtor::Never), _) => return true, 61 (Ty::Never, _) => return true,
62 62
63 // Trivial cases, this should go after `never` check to 63 // Trivial cases, this should go after `never` check to
64 // avoid infer result type to be never 64 // avoid infer result type to be never
@@ -71,38 +71,33 @@ impl<'a> InferenceContext<'a> {
71 71
72 // Pointer weakening and function to pointer 72 // Pointer weakening and function to pointer
73 match (&mut from_ty, to_ty) { 73 match (&mut from_ty, to_ty) {
74 // `*mut T`, `&mut T, `&T`` -> `*const T` 74 // `*mut T` -> `*const T`
75 // `&mut T` -> `&T` 75 // `&mut T` -> `&T`
76 // `&mut T` -> `*mut T` 76 (Ty::RawPtr(m1, ..), Ty::RawPtr(m2 @ Mutability::Shared, ..))
77 (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 77 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Shared, ..)) => {
78 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 78 *m1 = *m2;
79 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) 79 }
80 | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { 80 // `&T` -> `*const T`
81 *c1 = *c2; 81 // `&mut T` -> `*mut T`/`*const T`
82 (Ty::Ref(.., substs), &Ty::RawPtr(m2 @ Mutability::Shared, ..))
83 | (Ty::Ref(Mutability::Mut, substs), &Ty::RawPtr(m2, ..)) => {
84 from_ty = Ty::RawPtr(m2, substs.clone());
82 } 85 }
83 86
84 // Illegal mutablity conversion 87 // Illegal mutability conversion
85 ( 88 (Ty::RawPtr(Mutability::Shared, ..), Ty::RawPtr(Mutability::Mut, ..))
86 ty_app!(TypeCtor::RawPtr(Mutability::Shared)), 89 | (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false,
87 ty_app!(TypeCtor::RawPtr(Mutability::Mut)),
88 )
89 | (
90 ty_app!(TypeCtor::Ref(Mutability::Shared)),
91 ty_app!(TypeCtor::Ref(Mutability::Mut)),
92 ) => return false,
93 90
94 // `{function_type}` -> `fn()` 91 // `{function_type}` -> `fn()`
95 (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { 92 (Ty::FnDef(..), Ty::FnPtr { .. }) => match from_ty.callable_sig(self.db) {
96 match from_ty.callable_sig(self.db) { 93 None => return false,
97 None => return false, 94 Some(sig) => {
98 Some(sig) => { 95 from_ty = Ty::fn_ptr(sig);
99 from_ty = Ty::fn_ptr(sig);
100 }
101 } 96 }
102 } 97 },
103 98
104 (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { 99 (Ty::Closure { substs, .. }, Ty::FnPtr { .. }) => {
105 from_ty = params[0].clone(); 100 from_ty = substs[0].clone();
106 } 101 }
107 102
108 _ => {} 103 _ => {}
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> {
115 // Auto Deref if cannot coerce 110 // Auto Deref if cannot coerce
116 match (&from_ty, to_ty) { 111 match (&from_ty, to_ty) {
117 // FIXME: DerefMut 112 // FIXME: DerefMut
118 (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { 113 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]),
119 self.unify_autoderef_behind_ref(&st1[0], &st2[0])
120 }
121 114
122 // Otherwise, normal unify 115 // Otherwise, normal unify
123 _ => self.unify(&from_ty, to_ty), 116 _ => self.unify(&from_ty, to_ty),
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> {
178 }, 171 },
179 ) { 172 ) {
180 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 173 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
181 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 174 let from_ty = self.resolve_ty_shallow(&derefed_ty);
182 // Stop when constructor matches. 175 // Stop when constructor matches.
183 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { 176 if from_ty.equals_ctor(&to_ty) {
184 // It will not recurse to `coerce`. 177 // It will not recurse to `coerce`.
185 return self.table.unify_substs(st1, st2, 0); 178 return match (from_ty.substs(), to_ty.substs()) {
186 } 179 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
187 _ => { 180 (None, None) => true,
188 if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 181 _ => false,
189 return true; 182 };
190 } 183 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
191 } 184 return true;
192 } 185 }
193 } 186 }
194 187
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 3fec0e431..2369c9bef 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,8 +18,8 @@ use crate::{
18 primitive::{self, UintTy}, 18 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 19 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 20 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, 21 Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, Substs,
22 Scalar, Substs, TraitRef, Ty, TypeCtor, 22 TraitRef, Ty,
23}; 23};
24 24
25use super::{ 25use super::{
@@ -82,10 +82,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 82 arg_tys.push(arg);
83 } 83 }
84 let parameters = param_builder.build(); 84 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 85 let arg_ty = Ty::Tuple { cardinality: num_args as u16, substs: parameters };
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 86 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 87 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 88
@@ -120,10 +117,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 117 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 118 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 119 // if let is desugared to match, so this is always simple if
123 self.infer_expr( 120 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 *condition,
125 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
126 );
127 121
128 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 122 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
129 let mut both_arms_diverge = Diverges::Always; 123 let mut both_arms_diverge = Diverges::Always;
@@ -178,7 +172,7 @@ impl<'a> InferenceContext<'a> {
178 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 172 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
179 let inner_ty = self.infer_expr(*body, &Expectation::none()); 173 let inner_ty = self.infer_expr(*body, &Expectation::none());
180 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 174 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
181 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 175 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
182 } 176 }
183 Expr::Loop { body, label } => { 177 Expr::Loop { body, label } => {
184 self.breakables.push(BreakableContext { 178 self.breakables.push(BreakableContext {
@@ -196,7 +190,7 @@ impl<'a> InferenceContext<'a> {
196 if ctxt.may_break { 190 if ctxt.may_break {
197 ctxt.break_ty 191 ctxt.break_ty
198 } else { 192 } else {
199 Ty::simple(TypeCtor::Never) 193 Ty::Never
200 } 194 }
201 } 195 }
202 Expr::While { condition, body, label } => { 196 Expr::While { condition, body, label } => {
@@ -206,10 +200,7 @@ impl<'a> InferenceContext<'a> {
206 label: label.map(|label| self.body[label].name.clone()), 200 label: label.map(|label| self.body[label].name.clone()),
207 }); 201 });
208 // while let is desugared to a match loop, so this is always simple while 202 // while let is desugared to a match loop, so this is always simple while
209 self.infer_expr( 203 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
210 *condition,
211 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
212 );
213 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 204 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
214 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 205 let _ctxt = self.breakables.pop().expect("breakable stack broken");
215 // the body may not run, so it diverging doesn't mean we diverge 206 // the body may not run, so it diverging doesn't mean we diverge
@@ -256,12 +247,13 @@ impl<'a> InferenceContext<'a> {
256 None => self.table.new_type_var(), 247 None => self.table.new_type_var(),
257 }; 248 };
258 sig_tys.push(ret_ty.clone()); 249 sig_tys.push(ret_ty.clone());
259 let sig_ty = Ty::apply( 250 let sig_ty = Ty::FnPtr {
260 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 251 num_args: sig_tys.len() as u16 - 1,
261 Substs(sig_tys.clone().into()), 252 is_varargs: false,
262 ); 253 substs: Substs(sig_tys.clone().into()),
254 };
263 let closure_ty = 255 let closure_ty =
264 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 256 Ty::Closure { def: self.owner, expr: tgt_expr, substs: Substs::single(sig_ty) };
265 257
266 // Eagerly try to relate the closure type with the expected 258 // Eagerly try to relate the closure type with the expected
267 // type, otherwise we often won't have enough information to 259 // type, otherwise we often won't have enough information to
@@ -312,11 +304,8 @@ impl<'a> InferenceContext<'a> {
312 Expr::Match { expr, arms } => { 304 Expr::Match { expr, arms } => {
313 let input_ty = self.infer_expr(*expr, &Expectation::none()); 305 let input_ty = self.infer_expr(*expr, &Expectation::none());
314 306
315 let mut result_ty = if arms.is_empty() { 307 let mut result_ty =
316 Ty::simple(TypeCtor::Never) 308 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
317 } else {
318 self.table.new_type_var()
319 };
320 309
321 let matchee_diverges = self.diverges; 310 let matchee_diverges = self.diverges;
322 let mut all_arms_diverge = Diverges::Always; 311 let mut all_arms_diverge = Diverges::Always;
@@ -327,7 +316,7 @@ impl<'a> InferenceContext<'a> {
327 if let Some(guard_expr) = arm.guard { 316 if let Some(guard_expr) = arm.guard {
328 self.infer_expr( 317 self.infer_expr(
329 guard_expr, 318 guard_expr,
330 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), 319 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
331 ); 320 );
332 } 321 }
333 322
@@ -345,7 +334,7 @@ impl<'a> InferenceContext<'a> {
345 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 334 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
346 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 335 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
347 } 336 }
348 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 337 Expr::Continue { .. } => Ty::Never,
349 Expr::Break { expr, label } => { 338 Expr::Break { expr, label } => {
350 let val_ty = if let Some(expr) = expr { 339 let val_ty = if let Some(expr) = expr {
351 self.infer_expr(*expr, &Expectation::none()) 340 self.infer_expr(*expr, &Expectation::none())
@@ -370,8 +359,7 @@ impl<'a> InferenceContext<'a> {
370 expr: tgt_expr, 359 expr: tgt_expr,
371 }); 360 });
372 } 361 }
373 362 Ty::Never
374 Ty::simple(TypeCtor::Never)
375 } 363 }
376 Expr::Return { expr } => { 364 Expr::Return { expr } => {
377 if let Some(expr) = expr { 365 if let Some(expr) = expr {
@@ -380,14 +368,14 @@ impl<'a> InferenceContext<'a> {
380 let unit = Ty::unit(); 368 let unit = Ty::unit();
381 self.coerce(&unit, &self.return_ty.clone()); 369 self.coerce(&unit, &self.return_ty.clone());
382 } 370 }
383 Ty::simple(TypeCtor::Never) 371 Ty::Never
384 } 372 }
385 Expr::Yield { expr } => { 373 Expr::Yield { expr } => {
386 // FIXME: track yield type for coercion 374 // FIXME: track yield type for coercion
387 if let Some(expr) = expr { 375 if let Some(expr) = expr {
388 self.infer_expr(*expr, &Expectation::none()); 376 self.infer_expr(*expr, &Expectation::none());
389 } 377 }
390 Ty::simple(TypeCtor::Never) 378 Ty::Never
391 } 379 }
392 Expr::RecordLit { path, fields, spread } => { 380 Expr::RecordLit { path, fields, spread } => {
393 let (ty, def_id) = self.resolve_variant(path.as_ref()); 381 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -397,7 +385,7 @@ impl<'a> InferenceContext<'a> {
397 385
398 self.unify(&ty, &expected.ty); 386 self.unify(&ty, &expected.ty);
399 387
400 let substs = ty.substs().unwrap_or_else(Substs::empty); 388 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
401 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 389 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
402 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 390 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
403 for (field_idx, field) in fields.iter().enumerate() { 391 for (field_idx, field) in fields.iter().enumerate() {
@@ -436,30 +424,23 @@ impl<'a> InferenceContext<'a> {
436 }, 424 },
437 ) 425 )
438 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 426 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
439 Ty::Apply(a_ty) => match a_ty.ctor { 427 Ty::Tuple { substs, .. } => {
440 TypeCtor::Tuple { .. } => name 428 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
441 .as_tuple_index() 429 }
442 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 430 Ty::Adt(AdtId::StructId(s), parameters) => {
443 TypeCtor::Adt(AdtId::StructId(s)) => { 431 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
444 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 432 let field = FieldId { parent: s.into(), local_id };
445 let field = FieldId { parent: s.into(), local_id }; 433 self.write_field_resolution(tgt_expr, field);
446 self.write_field_resolution(tgt_expr, field); 434 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
447 self.db.field_types(s.into())[field.local_id] 435 })
448 .clone() 436 }
449 .subst(&a_ty.parameters) 437 Ty::Adt(AdtId::UnionId(u), parameters) => {
450 }) 438 self.db.union_data(u).variant_data.field(name).map(|local_id| {
451 } 439 let field = FieldId { parent: u.into(), local_id };
452 TypeCtor::Adt(AdtId::UnionId(u)) => { 440 self.write_field_resolution(tgt_expr, field);
453 self.db.union_data(u).variant_data.field(name).map(|local_id| { 441 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
454 let field = FieldId { parent: u.into(), local_id }; 442 })
455 self.write_field_resolution(tgt_expr, field); 443 }
456 self.db.field_types(u.into())[field.local_id]
457 .clone()
458 .subst(&a_ty.parameters)
459 })
460 }
461 _ => None,
462 },
463 _ => None, 444 _ => None,
464 }) 445 })
465 .unwrap_or(Ty::Unknown); 446 .unwrap_or(Ty::Unknown);
@@ -497,19 +478,18 @@ impl<'a> InferenceContext<'a> {
497 Expectation::none() 478 Expectation::none()
498 }; 479 };
499 let inner_ty = self.infer_expr_inner(*expr, &expectation); 480 let inner_ty = self.infer_expr_inner(*expr, &expectation);
500 let ty = match rawness { 481 match rawness {
501 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 482 Rawness::RawPtr => Ty::RawPtr(*mutability, Substs::single(inner_ty)),
502 Rawness::Ref => TypeCtor::Ref(*mutability), 483 Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)),
503 }; 484 }
504 Ty::apply_one(ty, inner_ty)
505 } 485 }
506 Expr::Box { expr } => { 486 Expr::Box { expr } => {
507 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 487 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
508 if let Some(box_) = self.resolve_boxed_box() { 488 if let Some(box_) = self.resolve_boxed_box() {
509 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 489 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
510 sb = sb.push(inner_ty); 490 sb = sb.push(inner_ty);
511 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 491 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
512 Ty::apply(TypeCtor::Adt(box_), sb.build()) 492 Ty::Adt(box_, sb.build())
513 } else { 493 } else {
514 Ty::Unknown 494 Ty::Unknown
515 } 495 }
@@ -539,14 +519,9 @@ impl<'a> InferenceContext<'a> {
539 UnaryOp::Neg => { 519 UnaryOp::Neg => {
540 match &inner_ty { 520 match &inner_ty {
541 // Fast path for builtins 521 // Fast path for builtins
542 Ty::Apply(ApplicationTy { 522 Ty::Scalar(Scalar::Int(_))
543 ctor: TypeCtor::Scalar(Scalar::Int(_)), 523 | Ty::Scalar(Scalar::Uint(_))
544 .. 524 | Ty::Scalar(Scalar::Float(_))
545 })
546 | Ty::Apply(ApplicationTy {
547 ctor: TypeCtor::Scalar(Scalar::Float(_)),
548 ..
549 })
550 | Ty::Infer(InferTy::IntVar(..)) 525 | Ty::Infer(InferTy::IntVar(..))
551 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, 526 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
552 // Otherwise we resolve via the std::ops::Neg trait 527 // Otherwise we resolve via the std::ops::Neg trait
@@ -557,18 +532,9 @@ impl<'a> InferenceContext<'a> {
557 UnaryOp::Not => { 532 UnaryOp::Not => {
558 match &inner_ty { 533 match &inner_ty {
559 // Fast path for builtins 534 // Fast path for builtins
560 Ty::Apply(ApplicationTy { 535 Ty::Scalar(Scalar::Bool)
561 ctor: TypeCtor::Scalar(Scalar::Bool), 536 | Ty::Scalar(Scalar::Int(_))
562 .. 537 | Ty::Scalar(Scalar::Uint(_))
563 })
564 | Ty::Apply(ApplicationTy {
565 ctor: TypeCtor::Scalar(Scalar::Int(_)),
566 ..
567 })
568 | Ty::Apply(ApplicationTy {
569 ctor: TypeCtor::Scalar(Scalar::Uint(_)),
570 ..
571 })
572 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 538 | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
573 // Otherwise we resolve via the std::ops::Not trait 539 // Otherwise we resolve via the std::ops::Not trait
574 _ => self 540 _ => self
@@ -580,9 +546,7 @@ impl<'a> InferenceContext<'a> {
580 Expr::BinaryOp { lhs, rhs, op } => match op { 546 Expr::BinaryOp { lhs, rhs, op } => match op {
581 Some(op) => { 547 Some(op) => {
582 let lhs_expectation = match op { 548 let lhs_expectation = match op {
583 BinaryOp::LogicOp(..) => { 549 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
584 Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool)))
585 }
586 _ => Expectation::none(), 550 _ => Expectation::none(),
587 }; 551 };
588 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 552 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -613,31 +577,31 @@ impl<'a> InferenceContext<'a> {
613 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 577 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
614 match (range_type, lhs_ty, rhs_ty) { 578 match (range_type, lhs_ty, rhs_ty) {
615 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 579 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
616 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 580 Some(adt) => Ty::Adt(adt, Substs::empty()),
617 None => Ty::Unknown, 581 None => Ty::Unknown,
618 }, 582 },
619 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 583 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
620 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 584 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
621 None => Ty::Unknown, 585 None => Ty::Unknown,
622 }, 586 },
623 (RangeOp::Inclusive, None, Some(ty)) => { 587 (RangeOp::Inclusive, None, Some(ty)) => {
624 match self.resolve_range_to_inclusive() { 588 match self.resolve_range_to_inclusive() {
625 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 589 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
626 None => Ty::Unknown, 590 None => Ty::Unknown,
627 } 591 }
628 } 592 }
629 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 593 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
630 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 594 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
631 None => Ty::Unknown, 595 None => Ty::Unknown,
632 }, 596 },
633 (RangeOp::Inclusive, Some(_), Some(ty)) => { 597 (RangeOp::Inclusive, Some(_), Some(ty)) => {
634 match self.resolve_range_inclusive() { 598 match self.resolve_range_inclusive() {
635 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 599 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
636 None => Ty::Unknown, 600 None => Ty::Unknown,
637 } 601 }
638 } 602 }
639 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 603 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
640 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 604 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
641 None => Ty::Unknown, 605 None => Ty::Unknown,
642 }, 606 },
643 (RangeOp::Inclusive, _, None) => Ty::Unknown, 607 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -671,7 +635,7 @@ impl<'a> InferenceContext<'a> {
671 } 635 }
672 Expr::Tuple { exprs } => { 636 Expr::Tuple { exprs } => {
673 let mut tys = match &expected.ty { 637 let mut tys = match &expected.ty {
674 ty_app!(TypeCtor::Tuple { .. }, st) => st 638 Ty::Tuple { substs, .. } => substs
675 .iter() 639 .iter()
676 .cloned() 640 .cloned()
677 .chain(repeat_with(|| self.table.new_type_var())) 641 .chain(repeat_with(|| self.table.new_type_var()))
@@ -684,15 +648,11 @@ impl<'a> InferenceContext<'a> {
684 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 648 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
685 } 649 }
686 650
687 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 651 Ty::Tuple { cardinality: tys.len() as u16, substs: Substs(tys.into()) }
688 } 652 }
689 Expr::Array(array) => { 653 Expr::Array(array) => {
690 let elem_ty = match &expected.ty { 654 let elem_ty = match &expected.ty {
691 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 655 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
692 #[allow(unreachable_patterns)]
693 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
694 st.as_single().clone()
695 }
696 _ => self.table.new_type_var(), 656 _ => self.table.new_type_var(),
697 }; 657 };
698 658
@@ -709,42 +669,38 @@ impl<'a> InferenceContext<'a> {
709 ); 669 );
710 self.infer_expr( 670 self.infer_expr(
711 *repeat, 671 *repeat,
712 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( 672 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
713 UintTy::Usize,
714 )))),
715 ); 673 );
716 } 674 }
717 } 675 }
718 676
719 Ty::apply_one(TypeCtor::Array, elem_ty) 677 Ty::Array(Substs::single(elem_ty))
720 } 678 }
721 Expr::Literal(lit) => match lit { 679 Expr::Literal(lit) => match lit {
722 Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), 680 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
723 Literal::String(..) => { 681 Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)),
724 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
725 }
726 Literal::ByteString(..) => { 682 Literal::ByteString(..) => {
727 let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); 683 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
728 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 684 let array_type = Ty::Array(Substs::single(byte_type));
729 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 685 Ty::Ref(Mutability::Shared, Substs::single(array_type))
730 } 686 }
731 Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), 687 Literal::Char(..) => Ty::Scalar(Scalar::Char),
732 Literal::Int(_v, ty) => match ty { 688 Literal::Int(_v, ty) => match ty {
733 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int( 689 Some(int_ty) => {
734 primitive::int_ty_from_builtin(*int_ty), 690 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
735 ))), 691 }
736 None => self.table.new_integer_var(), 692 None => self.table.new_integer_var(),
737 }, 693 },
738 Literal::Uint(_v, ty) => match ty { 694 Literal::Uint(_v, ty) => match ty {
739 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint( 695 Some(int_ty) => {
740 primitive::uint_ty_from_builtin(*int_ty), 696 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
741 ))), 697 }
742 None => self.table.new_integer_var(), 698 None => self.table.new_integer_var(),
743 }, 699 },
744 Literal::Float(_v, ty) => match ty { 700 Literal::Float(_v, ty) => match ty {
745 Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float( 701 Some(float_ty) => {
746 primitive::float_ty_from_builtin(*float_ty), 702 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
747 ))), 703 }
748 None => self.table.new_float_var(), 704 None => self.table.new_float_var(),
749 }, 705 },
750 }, 706 },
@@ -857,7 +813,7 @@ impl<'a> InferenceContext<'a> {
857 // Apply autoref so the below unification works correctly 813 // Apply autoref so the below unification works correctly
858 // FIXME: return correct autorefs from lookup_method 814 // FIXME: return correct autorefs from lookup_method
859 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 815 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
860 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 816 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
861 _ => derefed_receiver_ty, 817 _ => derefed_receiver_ty,
862 }; 818 };
863 self.unify(&expected_receiver_ty, &actual_receiver_ty); 819 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -934,30 +890,26 @@ impl<'a> InferenceContext<'a> {
934 } 890 }
935 891
936 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 892 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
937 if let Ty::Apply(a_ty) = callable_ty { 893 if let &Ty::FnDef(def, ref parameters) = callable_ty {
938 if let TypeCtor::FnDef(def) = a_ty.ctor { 894 let generic_predicates = self.db.generic_predicates(def.into());
939 let generic_predicates = self.db.generic_predicates(def.into()); 895 for predicate in generic_predicates.iter() {
940 for predicate in generic_predicates.iter() { 896 let predicate = predicate.clone().subst(parameters);
941 let predicate = predicate.clone().subst(&a_ty.parameters); 897 if let Some(obligation) = Obligation::from_predicate(predicate) {
942 if let Some(obligation) = Obligation::from_predicate(predicate) { 898 self.obligations.push(obligation);
943 self.obligations.push(obligation);
944 }
945 } 899 }
946 // add obligation for trait implementation, if this is a trait method 900 }
947 match def { 901 // add obligation for trait implementation, if this is a trait method
948 CallableDefId::FunctionId(f) => { 902 match def {
949 if let AssocContainerId::TraitId(trait_) = 903 CallableDefId::FunctionId(f) => {
950 f.lookup(self.db.upcast()).container 904 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
951 { 905 {
952 // construct a TraitDef 906 // construct a TraitDef
953 let substs = a_ty 907 let substs =
954 .parameters 908 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
955 .prefix(generics(self.db.upcast(), trait_.into()).len()); 909 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
956 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
957 }
958 } 910 }
959 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
960 } 911 }
912 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
961 } 913 }
962 } 914 }
963 } 915 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..e96e08c3c 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,7 @@ use hir_expand::name::Name;
13use test_utils::mark; 13use test_utils::mark;
14 14
15use super::{BindingMode, Expectation, InferenceContext}; 15use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 16use crate::{utils::variant_data, Substs, Ty};
17 17
18impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 19 fn infer_tuple_struct_pat(
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> {
32 } 32 }
33 self.unify(&ty, expected); 33 self.unify(&ty, expected);
34 34
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 35 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 36
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 38 let (pre, post) = match ellipsis {
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> {
71 71
72 self.unify(&ty, expected); 72 self.unify(&ty, expected);
73 73
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 74 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 75
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 77 for subpat in subpats {
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 140
141 Ty::apply( 141 Ty::Tuple { cardinality: inner_tys.len() as u16, substs: Substs(inner_tys.into()) }
142 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
143 Substs(inner_tys.into()),
144 )
145 } 142 }
146 Pat::Or(ref pats) => { 143 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 144 if let Some((first_pat, rest)) = pats.split_first() {
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 162 _ => &Ty::Unknown,
166 }; 163 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 164 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 165 Ty::Ref(*mutability, Substs::single(subty))
169 } 166 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 167 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 168 p.as_ref(),
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> {
198 195
199 let bound_ty = match mode { 196 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 197 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 198 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 199 }
203 BindingMode::Move => inner_ty.clone(), 200 BindingMode::Move => inner_ty.clone(),
204 }; 201 };
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 204 return inner_ty;
208 } 205 }
209 Pat::Slice { prefix, slice, suffix } => { 206 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 207 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 208 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 210 _ => (Ty::Slice, Ty::Unknown),
214 }; 211 };
215 212
216 for pat_id in prefix.iter().chain(suffix) { 213 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 214 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 215 }
219 216
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 217 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 218 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 219 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 220 }
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> {
239 }; 236 };
240 237
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 238 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 239 Ty::Adt(box_adt, Substs::single(inner_ty))
243 } 240 }
244 None => Ty::Unknown, 241 None => Ty::Unknown,
245 }, 242 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 57eb8cede..2852ad5bf 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -9,7 +9,7 @@ use test_utils::mark;
9use super::{InferenceContext, Obligation}; 9use super::{InferenceContext, Obligation};
10use crate::{ 10use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, 11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs,
12 Ty, TyKind, TypeCtor, TypeWalk, 12 Ty, TyKind, TypeWalk,
13}; 13};
14 14
15impl<'a> InferenceContext<'a> { 15impl<'a> InferenceContext<'a> {
@@ -257,12 +257,14 @@ impl InferenceTable {
257 // try to resolve type vars first 257 // try to resolve type vars first
258 let ty1 = self.resolve_ty_shallow(ty1); 258 let ty1 = self.resolve_ty_shallow(ty1);
259 let ty2 = self.resolve_ty_shallow(ty2); 259 let ty2 = self.resolve_ty_shallow(ty2);
260 match (&*ty1, &*ty2) { 260 if ty1.equals_ctor(&ty2) {
261 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { 261 match (ty1.substs(), ty2.substs()) {
262 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) 262 (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1),
263 (None, None) => true,
264 _ => false,
263 } 265 }
264 266 } else {
265 _ => self.unify_inner_trivial(&ty1, &ty2, depth), 267 self.unify_inner_trivial(&ty1, &ty2, depth)
266 } 268 }
267 } 269 }
268 270
@@ -300,24 +302,12 @@ impl InferenceTable {
300 | (other, Ty::Infer(InferTy::TypeVar(tv))) 302 | (other, Ty::Infer(InferTy::TypeVar(tv)))
301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) 303 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other)
302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) 304 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv)))
303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_)))) 305 | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Int(_)))
304 | (other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))), Ty::Infer(InferTy::IntVar(tv))) 306 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::Infer(InferTy::IntVar(tv)))
305 | ( 307 | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Uint(_)))
306 Ty::Infer(InferTy::IntVar(tv)), 308 | (other @ Ty::Scalar(Scalar::Uint(_)), Ty::Infer(InferTy::IntVar(tv)))
307 other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), 309 | (Ty::Infer(InferTy::FloatVar(tv)), other @ Ty::Scalar(Scalar::Float(_)))
308 ) 310 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => {
309 | (
310 other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))),
311 Ty::Infer(InferTy::IntVar(tv)),
312 )
313 | (
314 Ty::Infer(InferTy::FloatVar(tv)),
315 other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))),
316 )
317 | (
318 other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))),
319 Ty::Infer(InferTy::FloatVar(tv)),
320 ) => {
321 // the type var is unknown since we tried to resolve it 311 // the type var is unknown since we tried to resolve it
322 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 312 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
323 true 313 true