diff options
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 249 |
1 files changed, 143 insertions, 106 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 262177ffb..55163c963 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -18,10 +18,11 @@ use crate::{ | |||
18 | lower::lower_to_chalk_mutability, | 18 | lower::lower_to_chalk_mutability, |
19 | method_resolution, op, | 19 | method_resolution, op, |
20 | primitive::{self, UintTy}, | 20 | primitive::{self, UintTy}, |
21 | traits::{FnTrait, InEnvironment}, | 21 | to_assoc_type_id, |
22 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, | ||
22 | utils::{generics, variant_data, Generics}, | 23 | utils::{generics, variant_data, Generics}, |
23 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, | 24 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs, |
24 | Substs, TraitRef, Ty, | 25 | TraitRef, Ty, TyKind, |
25 | }; | 26 | }; |
26 | 27 | ||
27 | use super::{ | 28 | use super::{ |
@@ -57,7 +58,7 @@ impl<'a> InferenceContext<'a> { | |||
57 | // Return actual type when type mismatch. | 58 | // Return actual type when type mismatch. |
58 | // This is needed for diagnostic when return type mismatch. | 59 | // This is needed for diagnostic when return type mismatch. |
59 | ty | 60 | ty |
60 | } else if expected.coercion_target() == &Ty::Unknown { | 61 | } else if expected.coercion_target().is_unknown() { |
61 | ty | 62 | ty |
62 | } else { | 63 | } else { |
63 | expected.ty.clone() | 64 | expected.ty.clone() |
@@ -84,7 +85,7 @@ impl<'a> InferenceContext<'a> { | |||
84 | arg_tys.push(arg); | 85 | arg_tys.push(arg); |
85 | } | 86 | } |
86 | let parameters = param_builder.build(); | 87 | let parameters = param_builder.build(); |
87 | let arg_ty = Ty::Tuple(num_args, parameters); | 88 | let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); |
88 | let substs = | 89 | let substs = |
89 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
90 | 91 | ||
@@ -97,8 +98,10 @@ impl<'a> InferenceContext<'a> { | |||
97 | }); | 98 | }); |
98 | if self.db.trait_solve(krate, goal.value).is_some() { | 99 | if self.db.trait_solve(krate, goal.value).is_some() { |
99 | self.obligations.push(implements_fn_trait); | 100 | self.obligations.push(implements_fn_trait); |
100 | let output_proj_ty = | 101 | let output_proj_ty = crate::ProjectionTy { |
101 | crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; | 102 | associated_ty_id: to_assoc_type_id(output_assoc_type), |
103 | substitution: substs, | ||
104 | }; | ||
102 | let return_ty = self.normalize_projection_ty(output_proj_ty); | 105 | let return_ty = self.normalize_projection_ty(output_proj_ty); |
103 | Some((arg_tys, return_ty)) | 106 | Some((arg_tys, return_ty)) |
104 | } else { | 107 | } else { |
@@ -116,10 +119,13 @@ impl<'a> InferenceContext<'a> { | |||
116 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 119 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
117 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 120 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
118 | let ty = match &body[tgt_expr] { | 121 | let ty = match &body[tgt_expr] { |
119 | Expr::Missing => Ty::Unknown, | 122 | Expr::Missing => self.err_ty(), |
120 | Expr::If { condition, then_branch, else_branch } => { | 123 | Expr::If { condition, then_branch, else_branch } => { |
121 | // if let is desugared to match, so this is always simple if | 124 | // if let is desugared to match, so this is always simple if |
122 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 125 | self.infer_expr( |
126 | *condition, | ||
127 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
128 | ); | ||
123 | 129 | ||
124 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 130 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
125 | let mut both_arms_diverge = Diverges::Always; | 131 | let mut both_arms_diverge = Diverges::Always; |
@@ -167,14 +173,15 @@ impl<'a> InferenceContext<'a> { | |||
167 | Expr::TryBlock { body } => { | 173 | Expr::TryBlock { body } => { |
168 | let _inner = self.infer_expr(*body, expected); | 174 | let _inner = self.infer_expr(*body, expected); |
169 | // FIXME should be std::result::Result<{inner}, _> | 175 | // FIXME should be std::result::Result<{inner}, _> |
170 | Ty::Unknown | 176 | self.err_ty() |
171 | } | 177 | } |
172 | Expr::Async { body } => { | 178 | Expr::Async { body } => { |
173 | // Use the first type parameter as the output type of future. | 179 | // Use the first type parameter as the output type of future. |
174 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 180 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
175 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 181 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
176 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 182 | let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); |
177 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) | 183 | let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); |
184 | TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner) | ||
178 | } | 185 | } |
179 | Expr::Loop { body, label } => { | 186 | Expr::Loop { body, label } => { |
180 | self.breakables.push(BreakableContext { | 187 | self.breakables.push(BreakableContext { |
@@ -192,17 +199,20 @@ impl<'a> InferenceContext<'a> { | |||
192 | if ctxt.may_break { | 199 | if ctxt.may_break { |
193 | ctxt.break_ty | 200 | ctxt.break_ty |
194 | } else { | 201 | } else { |
195 | Ty::Never | 202 | TyKind::Never.intern(&Interner) |
196 | } | 203 | } |
197 | } | 204 | } |
198 | Expr::While { condition, body, label } => { | 205 | Expr::While { condition, body, label } => { |
199 | self.breakables.push(BreakableContext { | 206 | self.breakables.push(BreakableContext { |
200 | may_break: false, | 207 | may_break: false, |
201 | break_ty: Ty::Unknown, | 208 | break_ty: self.err_ty(), |
202 | label: label.map(|label| self.body[label].name.clone()), | 209 | label: label.map(|label| self.body[label].name.clone()), |
203 | }); | 210 | }); |
204 | // while let is desugared to a match loop, so this is always simple while | 211 | // while let is desugared to a match loop, so this is always simple while |
205 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 212 | self.infer_expr( |
213 | *condition, | ||
214 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
215 | ); | ||
206 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 216 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
207 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 217 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
208 | // the body may not run, so it diverging doesn't mean we diverge | 218 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -214,7 +224,7 @@ impl<'a> InferenceContext<'a> { | |||
214 | 224 | ||
215 | self.breakables.push(BreakableContext { | 225 | self.breakables.push(BreakableContext { |
216 | may_break: false, | 226 | may_break: false, |
217 | break_ty: Ty::Unknown, | 227 | break_ty: self.err_ty(), |
218 | label: label.map(|label| self.body[label].name.clone()), | 228 | label: label.map(|label| self.body[label].name.clone()), |
219 | }); | 229 | }); |
220 | let pat_ty = | 230 | let pat_ty = |
@@ -249,12 +259,15 @@ impl<'a> InferenceContext<'a> { | |||
249 | None => self.table.new_type_var(), | 259 | None => self.table.new_type_var(), |
250 | }; | 260 | }; |
251 | sig_tys.push(ret_ty.clone()); | 261 | sig_tys.push(ret_ty.clone()); |
252 | let sig_ty = Ty::Function(FnPointer { | 262 | let sig_ty = TyKind::Function(FnPointer { |
253 | num_args: sig_tys.len() - 1, | 263 | num_args: sig_tys.len() - 1, |
254 | sig: FnSig { variadic: false }, | 264 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, |
255 | substs: Substs(sig_tys.clone().into()), | 265 | substs: Substs(sig_tys.clone().into()), |
256 | }); | 266 | }) |
257 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); | 267 | .intern(&Interner); |
268 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); | ||
269 | let closure_ty = | ||
270 | TyKind::Closure(closure_id, Substs::single(sig_ty)).intern(&Interner); | ||
258 | 271 | ||
259 | // Eagerly try to relate the closure type with the expected | 272 | // Eagerly try to relate the closure type with the expected |
260 | // type, otherwise we often won't have enough information to | 273 | // type, otherwise we often won't have enough information to |
@@ -295,7 +308,7 @@ impl<'a> InferenceContext<'a> { | |||
295 | args.len(), | 308 | args.len(), |
296 | ) | 309 | ) |
297 | }) | 310 | }) |
298 | .unwrap_or((Vec::new(), Ty::Unknown)); | 311 | .unwrap_or((Vec::new(), self.err_ty())); |
299 | self.register_obligations_for_call(&callee_ty); | 312 | self.register_obligations_for_call(&callee_ty); |
300 | self.check_call_arguments(args, ¶m_tys); | 313 | self.check_call_arguments(args, ¶m_tys); |
301 | self.normalize_associated_types_in(ret_ty) | 314 | self.normalize_associated_types_in(ret_ty) |
@@ -305,8 +318,11 @@ impl<'a> InferenceContext<'a> { | |||
305 | Expr::Match { expr, arms } => { | 318 | Expr::Match { expr, arms } => { |
306 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 319 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
307 | 320 | ||
308 | let mut result_ty = | 321 | let mut result_ty = if arms.is_empty() { |
309 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; | 322 | TyKind::Never.intern(&Interner) |
323 | } else { | ||
324 | self.table.new_type_var() | ||
325 | }; | ||
310 | 326 | ||
311 | let matchee_diverges = self.diverges; | 327 | let matchee_diverges = self.diverges; |
312 | let mut all_arms_diverge = Diverges::Always; | 328 | let mut all_arms_diverge = Diverges::Always; |
@@ -317,7 +333,7 @@ impl<'a> InferenceContext<'a> { | |||
317 | if let Some(guard_expr) = arm.guard { | 333 | if let Some(guard_expr) = arm.guard { |
318 | self.infer_expr( | 334 | self.infer_expr( |
319 | guard_expr, | 335 | guard_expr, |
320 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 336 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), |
321 | ); | 337 | ); |
322 | } | 338 | } |
323 | 339 | ||
@@ -333,9 +349,9 @@ impl<'a> InferenceContext<'a> { | |||
333 | Expr::Path(p) => { | 349 | Expr::Path(p) => { |
334 | // FIXME this could be more efficient... | 350 | // FIXME this could be more efficient... |
335 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 351 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
336 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 352 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty()) |
337 | } | 353 | } |
338 | Expr::Continue { .. } => Ty::Never, | 354 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), |
339 | Expr::Break { expr, label } => { | 355 | Expr::Break { expr, label } => { |
340 | let val_ty = if let Some(expr) = expr { | 356 | let val_ty = if let Some(expr) = expr { |
341 | self.infer_expr(*expr, &Expectation::none()) | 357 | self.infer_expr(*expr, &Expectation::none()) |
@@ -347,7 +363,7 @@ impl<'a> InferenceContext<'a> { | |||
347 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 363 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
348 | ctxt.break_ty.clone() | 364 | ctxt.break_ty.clone() |
349 | } else { | 365 | } else { |
350 | Ty::Unknown | 366 | self.err_ty() |
351 | }; | 367 | }; |
352 | 368 | ||
353 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | 369 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); |
@@ -360,7 +376,7 @@ impl<'a> InferenceContext<'a> { | |||
360 | expr: tgt_expr, | 376 | expr: tgt_expr, |
361 | }); | 377 | }); |
362 | } | 378 | } |
363 | Ty::Never | 379 | TyKind::Never.intern(&Interner) |
364 | } | 380 | } |
365 | Expr::Return { expr } => { | 381 | Expr::Return { expr } => { |
366 | if let Some(expr) = expr { | 382 | if let Some(expr) = expr { |
@@ -369,14 +385,14 @@ impl<'a> InferenceContext<'a> { | |||
369 | let unit = Ty::unit(); | 385 | let unit = Ty::unit(); |
370 | self.coerce(&unit, &self.return_ty.clone()); | 386 | self.coerce(&unit, &self.return_ty.clone()); |
371 | } | 387 | } |
372 | Ty::Never | 388 | TyKind::Never.intern(&Interner) |
373 | } | 389 | } |
374 | Expr::Yield { expr } => { | 390 | Expr::Yield { expr } => { |
375 | // FIXME: track yield type for coercion | 391 | // FIXME: track yield type for coercion |
376 | if let Some(expr) = expr { | 392 | if let Some(expr) = expr { |
377 | self.infer_expr(*expr, &Expectation::none()); | 393 | self.infer_expr(*expr, &Expectation::none()); |
378 | } | 394 | } |
379 | Ty::Never | 395 | TyKind::Never.intern(&Interner) |
380 | } | 396 | } |
381 | Expr::RecordLit { path, fields, spread } => { | 397 | Expr::RecordLit { path, fields, spread } => { |
382 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 398 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -404,8 +420,9 @@ impl<'a> InferenceContext<'a> { | |||
404 | if let Some(field_def) = field_def { | 420 | if let Some(field_def) = field_def { |
405 | self.result.record_field_resolutions.insert(field.expr, field_def); | 421 | self.result.record_field_resolutions.insert(field.expr, field_def); |
406 | } | 422 | } |
407 | let field_ty = field_def | 423 | let field_ty = field_def.map_or(self.err_ty(), |it| { |
408 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); | 424 | field_types[it.local_id].clone().subst(&substs) |
425 | }); | ||
409 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 426 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
410 | } | 427 | } |
411 | if let Some(expr) = spread { | 428 | if let Some(expr) = spread { |
@@ -424,27 +441,33 @@ impl<'a> InferenceContext<'a> { | |||
424 | environment: self.trait_env.clone(), | 441 | environment: self.trait_env.clone(), |
425 | }, | 442 | }, |
426 | ) | 443 | ) |
427 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 444 | .find_map(|derefed_ty| { |
428 | Ty::Tuple(_, substs) => { | 445 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { |
429 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 446 | TyKind::Tuple(_, substs) => { |
430 | } | 447 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
431 | Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 448 | } |
432 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 449 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
433 | let field = FieldId { parent: s.into(), local_id }; | 450 | self.db.struct_data(*s).variant_data.field(name).map(|local_id| { |
434 | self.write_field_resolution(tgt_expr, field); | 451 | let field = FieldId { parent: (*s).into(), local_id }; |
435 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) | 452 | self.write_field_resolution(tgt_expr, field); |
436 | }) | 453 | self.db.field_types((*s).into())[field.local_id] |
437 | } | 454 | .clone() |
438 | Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { | 455 | .subst(¶meters) |
439 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 456 | }) |
440 | let field = FieldId { parent: u.into(), local_id }; | 457 | } |
441 | self.write_field_resolution(tgt_expr, field); | 458 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { |
442 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) | 459 | self.db.union_data(*u).variant_data.field(name).map(|local_id| { |
443 | }) | 460 | let field = FieldId { parent: (*u).into(), local_id }; |
461 | self.write_field_resolution(tgt_expr, field); | ||
462 | self.db.field_types((*u).into())[field.local_id] | ||
463 | .clone() | ||
464 | .subst(¶meters) | ||
465 | }) | ||
466 | } | ||
467 | _ => None, | ||
444 | } | 468 | } |
445 | _ => None, | ||
446 | }) | 469 | }) |
447 | .unwrap_or(Ty::Unknown); | 470 | .unwrap_or(self.err_ty()); |
448 | let ty = self.insert_type_vars(ty); | 471 | let ty = self.insert_type_vars(ty); |
449 | self.normalize_associated_types_in(ty) | 472 | self.normalize_associated_types_in(ty) |
450 | } | 473 | } |
@@ -481,9 +504,10 @@ impl<'a> InferenceContext<'a> { | |||
481 | }; | 504 | }; |
482 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 505 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
483 | match rawness { | 506 | match rawness { |
484 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), | 507 | Rawness::RawPtr => TyKind::Raw(mutability, Substs::single(inner_ty)), |
485 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), | 508 | Rawness::Ref => TyKind::Ref(mutability, Substs::single(inner_ty)), |
486 | } | 509 | } |
510 | .intern(&Interner) | ||
487 | } | 511 | } |
488 | Expr::Box { expr } => { | 512 | Expr::Box { expr } => { |
489 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 513 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
@@ -499,7 +523,7 @@ impl<'a> InferenceContext<'a> { | |||
499 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 523 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
500 | Ty::adt_ty(box_, sb.build()) | 524 | Ty::adt_ty(box_, sb.build()) |
501 | } else { | 525 | } else { |
502 | Ty::Unknown | 526 | self.err_ty() |
503 | } | 527 | } |
504 | } | 528 | } |
505 | Expr::UnaryOp { expr, op } => { | 529 | Expr::UnaryOp { expr, op } => { |
@@ -519,31 +543,31 @@ impl<'a> InferenceContext<'a> { | |||
519 | Some(derefed_ty) => { | 543 | Some(derefed_ty) => { |
520 | canonicalized.decanonicalize_ty(derefed_ty.value) | 544 | canonicalized.decanonicalize_ty(derefed_ty.value) |
521 | } | 545 | } |
522 | None => Ty::Unknown, | 546 | None => self.err_ty(), |
523 | } | 547 | } |
524 | } | 548 | } |
525 | None => Ty::Unknown, | 549 | None => self.err_ty(), |
526 | }, | 550 | }, |
527 | UnaryOp::Neg => { | 551 | UnaryOp::Neg => { |
528 | match &inner_ty { | 552 | match inner_ty.interned(&Interner) { |
529 | // Fast path for builtins | 553 | // Fast path for builtins |
530 | Ty::Scalar(Scalar::Int(_)) | 554 | TyKind::Scalar(Scalar::Int(_)) |
531 | | Ty::Scalar(Scalar::Uint(_)) | 555 | | TyKind::Scalar(Scalar::Uint(_)) |
532 | | Ty::Scalar(Scalar::Float(_)) | 556 | | TyKind::Scalar(Scalar::Float(_)) |
533 | | Ty::InferenceVar(_, TyVariableKind::Integer) | 557 | | TyKind::InferenceVar(_, TyVariableKind::Integer) |
534 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, | 558 | | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
535 | // Otherwise we resolve via the std::ops::Neg trait | 559 | // Otherwise we resolve via the std::ops::Neg trait |
536 | _ => self | 560 | _ => self |
537 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 561 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
538 | } | 562 | } |
539 | } | 563 | } |
540 | UnaryOp::Not => { | 564 | UnaryOp::Not => { |
541 | match &inner_ty { | 565 | match inner_ty.interned(&Interner) { |
542 | // Fast path for builtins | 566 | // Fast path for builtins |
543 | Ty::Scalar(Scalar::Bool) | 567 | TyKind::Scalar(Scalar::Bool) |
544 | | Ty::Scalar(Scalar::Int(_)) | 568 | | TyKind::Scalar(Scalar::Int(_)) |
545 | | Ty::Scalar(Scalar::Uint(_)) | 569 | | TyKind::Scalar(Scalar::Uint(_)) |
546 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | 570 | | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty, |
547 | // Otherwise we resolve via the std::ops::Not trait | 571 | // Otherwise we resolve via the std::ops::Not trait |
548 | _ => self | 572 | _ => self |
549 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 573 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -554,7 +578,9 @@ impl<'a> InferenceContext<'a> { | |||
554 | Expr::BinaryOp { lhs, rhs, op } => match op { | 578 | Expr::BinaryOp { lhs, rhs, op } => match op { |
555 | Some(op) => { | 579 | Some(op) => { |
556 | let lhs_expectation = match op { | 580 | let lhs_expectation = match op { |
557 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 581 | BinaryOp::LogicOp(..) => { |
582 | Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)) | ||
583 | } | ||
558 | _ => Expectation::none(), | 584 | _ => Expectation::none(), |
559 | }; | 585 | }; |
560 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 586 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -563,7 +589,7 @@ impl<'a> InferenceContext<'a> { | |||
563 | 589 | ||
564 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); | 590 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); |
565 | 591 | ||
566 | if ret == Ty::Unknown { | 592 | if ret.is_unknown() { |
567 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); | 593 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); |
568 | 594 | ||
569 | self.resolve_associated_type_with_params( | 595 | self.resolve_associated_type_with_params( |
@@ -575,7 +601,7 @@ impl<'a> InferenceContext<'a> { | |||
575 | ret | 601 | ret |
576 | } | 602 | } |
577 | } | 603 | } |
578 | _ => Ty::Unknown, | 604 | _ => self.err_ty(), |
579 | }, | 605 | }, |
580 | Expr::Range { lhs, rhs, range_type } => { | 606 | Expr::Range { lhs, rhs, range_type } => { |
581 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); | 607 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); |
@@ -586,33 +612,33 @@ impl<'a> InferenceContext<'a> { | |||
586 | match (range_type, lhs_ty, rhs_ty) { | 612 | match (range_type, lhs_ty, rhs_ty) { |
587 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 613 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
588 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), | 614 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), |
589 | None => Ty::Unknown, | 615 | None => self.err_ty(), |
590 | }, | 616 | }, |
591 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 617 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
592 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 618 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
593 | None => Ty::Unknown, | 619 | None => self.err_ty(), |
594 | }, | 620 | }, |
595 | (RangeOp::Inclusive, None, Some(ty)) => { | 621 | (RangeOp::Inclusive, None, Some(ty)) => { |
596 | match self.resolve_range_to_inclusive() { | 622 | match self.resolve_range_to_inclusive() { |
597 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 623 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
598 | None => Ty::Unknown, | 624 | None => self.err_ty(), |
599 | } | 625 | } |
600 | } | 626 | } |
601 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 627 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
602 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 628 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
603 | None => Ty::Unknown, | 629 | None => self.err_ty(), |
604 | }, | 630 | }, |
605 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 631 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
606 | match self.resolve_range_inclusive() { | 632 | match self.resolve_range_inclusive() { |
607 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 633 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
608 | None => Ty::Unknown, | 634 | None => self.err_ty(), |
609 | } | 635 | } |
610 | } | 636 | } |
611 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 637 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
612 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 638 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
613 | None => Ty::Unknown, | 639 | None => self.err_ty(), |
614 | }, | 640 | }, |
615 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 641 | (RangeOp::Inclusive, _, None) => self.err_ty(), |
616 | } | 642 | } |
617 | } | 643 | } |
618 | Expr::Index { base, index } => { | 644 | Expr::Index { base, index } => { |
@@ -631,19 +657,19 @@ impl<'a> InferenceContext<'a> { | |||
631 | index_trait, | 657 | index_trait, |
632 | ); | 658 | ); |
633 | let self_ty = | 659 | let self_ty = |
634 | self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); | 660 | self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value)); |
635 | self.resolve_associated_type_with_params( | 661 | self.resolve_associated_type_with_params( |
636 | self_ty, | 662 | self_ty, |
637 | self.resolve_ops_index_output(), | 663 | self.resolve_ops_index_output(), |
638 | &[index_ty], | 664 | &[index_ty], |
639 | ) | 665 | ) |
640 | } else { | 666 | } else { |
641 | Ty::Unknown | 667 | self.err_ty() |
642 | } | 668 | } |
643 | } | 669 | } |
644 | Expr::Tuple { exprs } => { | 670 | Expr::Tuple { exprs } => { |
645 | let mut tys = match &expected.ty { | 671 | let mut tys = match expected.ty.interned(&Interner) { |
646 | Ty::Tuple(_, substs) => substs | 672 | TyKind::Tuple(_, substs) => substs |
647 | .iter() | 673 | .iter() |
648 | .cloned() | 674 | .cloned() |
649 | .chain(repeat_with(|| self.table.new_type_var())) | 675 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -656,11 +682,11 @@ impl<'a> InferenceContext<'a> { | |||
656 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 682 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
657 | } | 683 | } |
658 | 684 | ||
659 | Ty::Tuple(tys.len(), Substs(tys.into())) | 685 | TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner) |
660 | } | 686 | } |
661 | Expr::Array(array) => { | 687 | Expr::Array(array) => { |
662 | let elem_ty = match &expected.ty { | 688 | let elem_ty = match expected.ty.interned(&Interner) { |
663 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), | 689 | TyKind::Array(st) | TyKind::Slice(st) => st.as_single().clone(), |
664 | _ => self.table.new_type_var(), | 690 | _ => self.table.new_type_var(), |
665 | }; | 691 | }; |
666 | 692 | ||
@@ -677,43 +703,51 @@ impl<'a> InferenceContext<'a> { | |||
677 | ); | 703 | ); |
678 | self.infer_expr( | 704 | self.infer_expr( |
679 | *repeat, | 705 | *repeat, |
680 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), | 706 | &Expectation::has_type( |
707 | TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), | ||
708 | ), | ||
681 | ); | 709 | ); |
682 | } | 710 | } |
683 | } | 711 | } |
684 | 712 | ||
685 | Ty::Array(Substs::single(elem_ty)) | 713 | TyKind::Array(Substs::single(elem_ty)).intern(&Interner) |
686 | } | 714 | } |
687 | Expr::Literal(lit) => match lit { | 715 | Expr::Literal(lit) => match lit { |
688 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), | 716 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
689 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), | 717 | Literal::String(..) => { |
718 | TyKind::Ref(Mutability::Not, Substs::single(TyKind::Str.intern(&Interner))) | ||
719 | .intern(&Interner) | ||
720 | } | ||
690 | Literal::ByteString(..) => { | 721 | Literal::ByteString(..) => { |
691 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); | 722 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
692 | let array_type = Ty::Array(Substs::single(byte_type)); | 723 | let array_type = TyKind::Array(Substs::single(byte_type)).intern(&Interner); |
693 | Ty::Ref(Mutability::Not, Substs::single(array_type)) | 724 | TyKind::Ref(Mutability::Not, Substs::single(array_type)).intern(&Interner) |
694 | } | 725 | } |
695 | Literal::Char(..) => Ty::Scalar(Scalar::Char), | 726 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
696 | Literal::Int(_v, ty) => match ty { | 727 | Literal::Int(_v, ty) => match ty { |
697 | Some(int_ty) => { | 728 | Some(int_ty) => { |
698 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | 729 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
730 | .intern(&Interner) | ||
699 | } | 731 | } |
700 | None => self.table.new_integer_var(), | 732 | None => self.table.new_integer_var(), |
701 | }, | 733 | }, |
702 | Literal::Uint(_v, ty) => match ty { | 734 | Literal::Uint(_v, ty) => match ty { |
703 | Some(int_ty) => { | 735 | Some(int_ty) => { |
704 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | 736 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
737 | .intern(&Interner) | ||
705 | } | 738 | } |
706 | None => self.table.new_integer_var(), | 739 | None => self.table.new_integer_var(), |
707 | }, | 740 | }, |
708 | Literal::Float(_v, ty) => match ty { | 741 | Literal::Float(_v, ty) => match ty { |
709 | Some(float_ty) => { | 742 | Some(float_ty) => { |
710 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | 743 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
744 | .intern(&Interner) | ||
711 | } | 745 | } |
712 | None => self.table.new_float_var(), | 746 | None => self.table.new_float_var(), |
713 | }, | 747 | }, |
714 | }, | 748 | }, |
715 | }; | 749 | }; |
716 | // use a new type variable if we got Ty::Unknown here | 750 | // use a new type variable if we got unknown here |
717 | let ty = self.insert_type_vars_shallow(ty); | 751 | let ty = self.insert_type_vars_shallow(ty); |
718 | let ty = self.resolve_ty_as_possible(ty); | 752 | let ty = self.resolve_ty_as_possible(ty); |
719 | self.write_expr_ty(tgt_expr, ty.clone()); | 753 | self.write_expr_ty(tgt_expr, ty.clone()); |
@@ -730,7 +764,7 @@ impl<'a> InferenceContext<'a> { | |||
730 | match stmt { | 764 | match stmt { |
731 | Statement::Let { pat, type_ref, initializer } => { | 765 | Statement::Let { pat, type_ref, initializer } => { |
732 | let decl_ty = | 766 | let decl_ty = |
733 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); | 767 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty()); |
734 | 768 | ||
735 | // Always use the declared type when specified | 769 | // Always use the declared type when specified |
736 | let mut ty = decl_ty.clone(); | 770 | let mut ty = decl_ty.clone(); |
@@ -738,7 +772,7 @@ impl<'a> InferenceContext<'a> { | |||
738 | if let Some(expr) = initializer { | 772 | if let Some(expr) = initializer { |
739 | let actual_ty = | 773 | let actual_ty = |
740 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | 774 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); |
741 | if decl_ty == Ty::Unknown { | 775 | if decl_ty.is_unknown() { |
742 | ty = actual_ty; | 776 | ty = actual_ty; |
743 | } | 777 | } |
744 | } | 778 | } |
@@ -802,7 +836,7 @@ impl<'a> InferenceContext<'a> { | |||
802 | self.write_method_resolution(tgt_expr, func); | 836 | self.write_method_resolution(tgt_expr, func); |
803 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 837 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
804 | } | 838 | } |
805 | None => (receiver_ty, Binders::new(0, Ty::Unknown), None), | 839 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), |
806 | }; | 840 | }; |
807 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 841 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
808 | let method_ty = method_ty.subst(&substs); | 842 | let method_ty = method_ty.subst(&substs); |
@@ -813,15 +847,17 @@ impl<'a> InferenceContext<'a> { | |||
813 | if !sig.params().is_empty() { | 847 | if !sig.params().is_empty() { |
814 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) | 848 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) |
815 | } else { | 849 | } else { |
816 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | 850 | (self.err_ty(), Vec::new(), sig.ret().clone()) |
817 | } | 851 | } |
818 | } | 852 | } |
819 | None => (Ty::Unknown, Vec::new(), Ty::Unknown), | 853 | None => (self.err_ty(), Vec::new(), self.err_ty()), |
820 | }; | 854 | }; |
821 | // Apply autoref so the below unification works correctly | 855 | // Apply autoref so the below unification works correctly |
822 | // FIXME: return correct autorefs from lookup_method | 856 | // FIXME: return correct autorefs from lookup_method |
823 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 857 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
824 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), | 858 | Some((_, mutability)) => { |
859 | TyKind::Ref(mutability, Substs::single(derefed_receiver_ty)).intern(&Interner) | ||
860 | } | ||
825 | _ => derefed_receiver_ty, | 861 | _ => derefed_receiver_ty, |
826 | }; | 862 | }; |
827 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 863 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -837,7 +873,7 @@ impl<'a> InferenceContext<'a> { | |||
837 | // that we have more information about the types of arguments when we | 873 | // that we have more information about the types of arguments when we |
838 | // type-check the functions. This isn't really the right way to do this. | 874 | // type-check the functions. This isn't really the right way to do this. |
839 | for &check_closures in &[false, true] { | 875 | for &check_closures in &[false, true] { |
840 | let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); | 876 | let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty())); |
841 | for (&arg, param_ty) in args.iter().zip(param_iter) { | 877 | for (&arg, param_ty) in args.iter().zip(param_iter) { |
842 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); | 878 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); |
843 | if is_closure != check_closures { | 879 | if is_closure != check_closures { |
@@ -867,7 +903,7 @@ impl<'a> InferenceContext<'a> { | |||
867 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { | 903 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { |
868 | substs.push(receiver_ty.clone()); | 904 | substs.push(receiver_ty.clone()); |
869 | } else { | 905 | } else { |
870 | substs.push(Ty::Unknown); | 906 | substs.push(self.err_ty()); |
871 | } | 907 | } |
872 | } | 908 | } |
873 | } | 909 | } |
@@ -891,14 +927,15 @@ impl<'a> InferenceContext<'a> { | |||
891 | }; | 927 | }; |
892 | let supplied_params = substs.len(); | 928 | let supplied_params = substs.len(); |
893 | for _ in supplied_params..total_len { | 929 | for _ in supplied_params..total_len { |
894 | substs.push(Ty::Unknown); | 930 | substs.push(self.err_ty()); |
895 | } | 931 | } |
896 | assert_eq!(substs.len(), total_len); | 932 | assert_eq!(substs.len(), total_len); |
897 | Substs(substs.into()) | 933 | Substs(substs.into()) |
898 | } | 934 | } |
899 | 935 | ||
900 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 936 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
901 | if let &Ty::FnDef(def, ref parameters) = callable_ty { | 937 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { |
938 | let def: CallableDefId = from_chalk(self.db, *fn_def); | ||
902 | let generic_predicates = self.db.generic_predicates(def.into()); | 939 | let generic_predicates = self.db.generic_predicates(def.into()); |
903 | for predicate in generic_predicates.iter() { | 940 | for predicate in generic_predicates.iter() { |
904 | let predicate = predicate.clone().subst(parameters); | 941 | let predicate = predicate.clone().subst(parameters); |