diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 11 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/unsafe_check.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 178 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 17 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 79 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 245 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 27 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 38 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 521 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 51 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 124 | ||||
-rw-r--r-- | crates/hir_ty/src/op.rs | 39 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/simple.rs | 55 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 14 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 184 |
16 files changed, 735 insertions, 862 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index d740b7265..66a88e2b6 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | MissingPatFields, RemoveThisSemicolon, | 17 | MissingPatFields, RemoveThisSemicolon, |
18 | }, | 18 | }, |
19 | utils::variant_data, | 19 | utils::variant_data, |
20 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 20 | InferenceResult, Ty, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub(crate) use hir_def::{ | 23 | pub(crate) use hir_def::{ |
@@ -381,14 +381,11 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
381 | _ => return, | 381 | _ => return, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); | 384 | let (params, required) = match mismatch.expected { |
385 | let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); | 385 | Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_result_enum => { |
386 | |||
387 | let (params, required) = match &mismatch.expected { | ||
388 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => { | ||
389 | (parameters, "Ok".to_string()) | 386 | (parameters, "Ok".to_string()) |
390 | } | 387 | } |
391 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { | 388 | Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_option_enum => { |
392 | (parameters, "Some".to_string()) | 389 | (parameters, "Some".to_string()) |
393 | } | 390 | } |
394 | _ => return, | 391 | _ => return, |
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs index 1c1423fbf..86fee0050 100644 --- a/crates/hir_ty/src/diagnostics/match_check.rs +++ b/crates/hir_ty/src/diagnostics/match_check.rs | |||
@@ -227,7 +227,7 @@ use hir_def::{ | |||
227 | use la_arena::Idx; | 227 | use la_arena::Idx; |
228 | use smallvec::{smallvec, SmallVec}; | 228 | use smallvec::{smallvec, SmallVec}; |
229 | 229 | ||
230 | use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor}; | 230 | use crate::{db::HirDatabase, InferenceResult, Ty}; |
231 | 231 | ||
232 | #[derive(Debug, Clone, Copy)] | 232 | #[derive(Debug, Clone, Copy)] |
233 | /// Either a pattern from the source code being analyzed, represented as | 233 | /// Either a pattern from the source code being analyzed, represented as |
@@ -627,14 +627,12 @@ pub(super) fn is_useful( | |||
627 | // - `!` type | 627 | // - `!` type |
628 | // In those cases, no match arm is useful. | 628 | // In those cases, no match arm is useful. |
629 | match cx.infer[cx.match_expr].strip_references() { | 629 | match cx.infer[cx.match_expr].strip_references() { |
630 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => { | 630 | Ty::Adt(AdtId::EnumId(enum_id), ..) => { |
631 | if cx.db.enum_data(*enum_id).variants.is_empty() { | 631 | if cx.db.enum_data(*enum_id).variants.is_empty() { |
632 | return Ok(Usefulness::NotUseful); | 632 | return Ok(Usefulness::NotUseful); |
633 | } | 633 | } |
634 | } | 634 | } |
635 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => { | 635 | Ty::Never => return Ok(Usefulness::NotUseful), |
636 | return Ok(Usefulness::NotUseful); | ||
637 | } | ||
638 | _ => (), | 636 | _ => (), |
639 | } | 637 | } |
640 | 638 | ||
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index 9c506112d..b439915c7 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs | |||
@@ -11,9 +11,7 @@ use hir_def::{ | |||
11 | }; | 11 | }; |
12 | use hir_expand::diagnostics::DiagnosticSink; | 12 | use hir_expand::diagnostics::DiagnosticSink; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty}; |
15 | db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor, | ||
16 | }; | ||
17 | 15 | ||
18 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { | 16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { |
19 | owner: DefWithBodyId, | 17 | owner: DefWithBodyId, |
@@ -112,7 +110,7 @@ fn walk_unsafe( | |||
112 | } | 110 | } |
113 | } | 111 | } |
114 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { | 112 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { |
115 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { | 113 | if let Ty::RawPtr(..) = &infer[*expr] { |
116 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); | 114 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); |
117 | } | 115 | } |
118 | } | 116 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index b4801cb21..179f7ff44 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -3,9 +3,8 @@ | |||
3 | use std::{borrow::Cow, fmt}; | 3 | use std::{borrow::Cow, fmt}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | db::HirDatabase, primitive, utils::generics, ApplicationTy, CallableDefId, FnSig, | 6 | db::HirDatabase, primitive, utils::generics, CallableDefId, CallableSig, GenericPredicate, |
7 | GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, | 7 | Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty, |
8 | TraitRef, Ty, TypeCtor, | ||
9 | }; | 8 | }; |
10 | use arrayvec::ArrayVec; | 9 | use arrayvec::ArrayVec; |
11 | use hir_def::{ | 10 | use hir_def::{ |
@@ -235,39 +234,62 @@ impl HirDisplay for &Ty { | |||
235 | } | 234 | } |
236 | } | 235 | } |
237 | 236 | ||
238 | impl HirDisplay for ApplicationTy { | 237 | impl HirDisplay for ProjectionTy { |
239 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 238 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
240 | if f.should_truncate() { | 239 | if f.should_truncate() { |
241 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 240 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
242 | } | 241 | } |
243 | 242 | ||
244 | match self.ctor { | 243 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
245 | TypeCtor::Scalar(Scalar::Bool) => write!(f, "bool")?, | 244 | let first_parameter = self.parameters[0].into_displayable( |
246 | TypeCtor::Scalar(Scalar::Char) => write!(f, "char")?, | 245 | f.db, |
247 | TypeCtor::Scalar(Scalar::Float(t)) => { | 246 | f.max_size, |
248 | write!(f, "{}", primitive::float_ty_to_string(t))? | 247 | f.omit_verbose_types, |
249 | } | 248 | f.display_target, |
250 | TypeCtor::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, | 249 | ); |
251 | TypeCtor::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, | 250 | write!(f, "<{} as {}", first_parameter, trait_.name)?; |
252 | TypeCtor::Str => write!(f, "str")?, | 251 | if self.parameters.len() > 1 { |
253 | TypeCtor::Slice => { | 252 | write!(f, "<")?; |
254 | let t = self.parameters.as_single(); | 253 | f.write_joined(&self.parameters[1..], ", ")?; |
254 | write!(f, ">")?; | ||
255 | } | ||
256 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | ||
257 | Ok(()) | ||
258 | } | ||
259 | } | ||
260 | |||
261 | impl HirDisplay for Ty { | ||
262 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
263 | if f.should_truncate() { | ||
264 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
265 | } | ||
266 | |||
267 | match self { | ||
268 | Ty::Never => write!(f, "!")?, | ||
269 | Ty::Str => write!(f, "str")?, | ||
270 | Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, | ||
271 | Ty::Scalar(Scalar::Char) => write!(f, "char")?, | ||
272 | &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, | ||
273 | &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, | ||
274 | &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, | ||
275 | Ty::Slice(parameters) => { | ||
276 | let t = parameters.as_single(); | ||
255 | write!(f, "[")?; | 277 | write!(f, "[")?; |
256 | t.hir_fmt(f)?; | 278 | t.hir_fmt(f)?; |
257 | write!(f, "]")?; | 279 | write!(f, "]")?; |
258 | } | 280 | } |
259 | TypeCtor::Array => { | 281 | Ty::Array(parameters) => { |
260 | let t = self.parameters.as_single(); | 282 | let t = parameters.as_single(); |
261 | write!(f, "[")?; | 283 | write!(f, "[")?; |
262 | t.hir_fmt(f)?; | 284 | t.hir_fmt(f)?; |
263 | write!(f, "; _]")?; | 285 | write!(f, "; _]")?; |
264 | } | 286 | } |
265 | TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { | 287 | Ty::RawPtr(m, parameters) | Ty::Ref(m, parameters) => { |
266 | let t = self.parameters.as_single(); | 288 | let t = parameters.as_single(); |
267 | let ty_display = | 289 | let ty_display = |
268 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | 290 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); |
269 | 291 | ||
270 | if matches!(self.ctor, TypeCtor::RawPtr(_)) { | 292 | if matches!(self, Ty::RawPtr(..)) { |
271 | write!(f, "*{}", m.as_keyword_for_ptr())?; | 293 | write!(f, "*{}", m.as_keyword_for_ptr())?; |
272 | } else { | 294 | } else { |
273 | write!(f, "&{}", m.as_keyword_for_ref())?; | 295 | write!(f, "&{}", m.as_keyword_for_ref())?; |
@@ -308,25 +330,24 @@ impl HirDisplay for ApplicationTy { | |||
308 | write!(f, "{}", ty_display)?; | 330 | write!(f, "{}", ty_display)?; |
309 | } | 331 | } |
310 | } | 332 | } |
311 | TypeCtor::Never => write!(f, "!")?, | 333 | Ty::Tuple(_, substs) => { |
312 | TypeCtor::Tuple { .. } => { | 334 | if substs.len() == 1 { |
313 | let ts = &self.parameters; | ||
314 | if ts.len() == 1 { | ||
315 | write!(f, "(")?; | 335 | write!(f, "(")?; |
316 | ts[0].hir_fmt(f)?; | 336 | substs[0].hir_fmt(f)?; |
317 | write!(f, ",)")?; | 337 | write!(f, ",)")?; |
318 | } else { | 338 | } else { |
319 | write!(f, "(")?; | 339 | write!(f, "(")?; |
320 | f.write_joined(&*ts.0, ", ")?; | 340 | f.write_joined(&*substs.0, ", ")?; |
321 | write!(f, ")")?; | 341 | write!(f, ")")?; |
322 | } | 342 | } |
323 | } | 343 | } |
324 | TypeCtor::FnPtr { is_varargs, .. } => { | 344 | Ty::Function(fn_ptr) => { |
325 | let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); | 345 | let sig = CallableSig::from_fn_ptr(fn_ptr); |
326 | sig.hir_fmt(f)?; | 346 | sig.hir_fmt(f)?; |
327 | } | 347 | } |
328 | TypeCtor::FnDef(def) => { | 348 | Ty::FnDef(def, parameters) => { |
329 | let sig = f.db.callable_item_signature(def).subst(&self.parameters); | 349 | let def = *def; |
350 | let sig = f.db.callable_item_signature(def).subst(parameters); | ||
330 | match def { | 351 | match def { |
331 | CallableDefId::FunctionId(ff) => { | 352 | CallableDefId::FunctionId(ff) => { |
332 | write!(f, "fn {}", f.db.function_data(ff).name)? | 353 | write!(f, "fn {}", f.db.function_data(ff).name)? |
@@ -336,7 +357,7 @@ impl HirDisplay for ApplicationTy { | |||
336 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? | 357 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? |
337 | } | 358 | } |
338 | }; | 359 | }; |
339 | if self.parameters.len() > 0 { | 360 | if parameters.len() > 0 { |
340 | let generics = generics(f.db.upcast(), def.into()); | 361 | let generics = generics(f.db.upcast(), def.into()); |
341 | let (parent_params, self_param, type_params, _impl_trait_params) = | 362 | let (parent_params, self_param, type_params, _impl_trait_params) = |
342 | generics.provenance_split(); | 363 | generics.provenance_split(); |
@@ -344,7 +365,7 @@ impl HirDisplay for ApplicationTy { | |||
344 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? | 365 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? |
345 | if total_len > 0 { | 366 | if total_len > 0 { |
346 | write!(f, "<")?; | 367 | write!(f, "<")?; |
347 | f.write_joined(&self.parameters.0[..total_len], ", ")?; | 368 | f.write_joined(¶meters.0[..total_len], ", ")?; |
348 | write!(f, ">")?; | 369 | write!(f, ">")?; |
349 | } | 370 | } |
350 | } | 371 | } |
@@ -363,10 +384,10 @@ impl HirDisplay for ApplicationTy { | |||
363 | write!(f, " -> {}", ret_display)?; | 384 | write!(f, " -> {}", ret_display)?; |
364 | } | 385 | } |
365 | } | 386 | } |
366 | TypeCtor::Adt(def_id) => { | 387 | Ty::Adt(def_id, parameters) => { |
367 | match f.display_target { | 388 | match f.display_target { |
368 | DisplayTarget::Diagnostics | DisplayTarget::Test => { | 389 | DisplayTarget::Diagnostics | DisplayTarget::Test => { |
369 | let name = match def_id { | 390 | let name = match *def_id { |
370 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), | 391 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), |
371 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), | 392 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), |
372 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), | 393 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), |
@@ -376,7 +397,7 @@ impl HirDisplay for ApplicationTy { | |||
376 | DisplayTarget::SourceCode { module_id } => { | 397 | DisplayTarget::SourceCode { module_id } => { |
377 | if let Some(path) = find_path::find_path( | 398 | if let Some(path) = find_path::find_path( |
378 | f.db.upcast(), | 399 | f.db.upcast(), |
379 | ItemInNs::Types(def_id.into()), | 400 | ItemInNs::Types((*def_id).into()), |
380 | module_id, | 401 | module_id, |
381 | ) { | 402 | ) { |
382 | write!(f, "{}", path)?; | 403 | write!(f, "{}", path)?; |
@@ -388,19 +409,18 @@ impl HirDisplay for ApplicationTy { | |||
388 | } | 409 | } |
389 | } | 410 | } |
390 | 411 | ||
391 | if self.parameters.len() > 0 { | 412 | if parameters.len() > 0 { |
392 | let parameters_to_write = | 413 | let parameters_to_write = |
393 | if f.display_target.is_source_code() || f.omit_verbose_types() { | 414 | if f.display_target.is_source_code() || f.omit_verbose_types() { |
394 | match self | 415 | match self |
395 | .ctor | ||
396 | .as_generic_def() | 416 | .as_generic_def() |
397 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 417 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
398 | .filter(|defaults| !defaults.is_empty()) | 418 | .filter(|defaults| !defaults.is_empty()) |
399 | { | 419 | { |
400 | None => self.parameters.0.as_ref(), | 420 | None => parameters.0.as_ref(), |
401 | Some(default_parameters) => { | 421 | Some(default_parameters) => { |
402 | let mut default_from = 0; | 422 | let mut default_from = 0; |
403 | for (i, parameter) in self.parameters.iter().enumerate() { | 423 | for (i, parameter) in parameters.iter().enumerate() { |
404 | match (parameter, default_parameters.get(i)) { | 424 | match (parameter, default_parameters.get(i)) { |
405 | (&Ty::Unknown, _) | (_, None) => { | 425 | (&Ty::Unknown, _) | (_, None) => { |
406 | default_from = i + 1; | 426 | default_from = i + 1; |
@@ -408,18 +428,18 @@ impl HirDisplay for ApplicationTy { | |||
408 | (_, Some(default_parameter)) => { | 428 | (_, Some(default_parameter)) => { |
409 | let actual_default = default_parameter | 429 | let actual_default = default_parameter |
410 | .clone() | 430 | .clone() |
411 | .subst(&self.parameters.prefix(i)); | 431 | .subst(¶meters.prefix(i)); |
412 | if parameter != &actual_default { | 432 | if parameter != &actual_default { |
413 | default_from = i + 1; | 433 | default_from = i + 1; |
414 | } | 434 | } |
415 | } | 435 | } |
416 | } | 436 | } |
417 | } | 437 | } |
418 | &self.parameters.0[0..default_from] | 438 | ¶meters.0[0..default_from] |
419 | } | 439 | } |
420 | } | 440 | } |
421 | } else { | 441 | } else { |
422 | self.parameters.0.as_ref() | 442 | parameters.0.as_ref() |
423 | }; | 443 | }; |
424 | if !parameters_to_write.is_empty() { | 444 | if !parameters_to_write.is_empty() { |
425 | write!(f, "<")?; | 445 | write!(f, "<")?; |
@@ -428,61 +448,54 @@ impl HirDisplay for ApplicationTy { | |||
428 | } | 448 | } |
429 | } | 449 | } |
430 | } | 450 | } |
431 | TypeCtor::AssociatedType(type_alias) => { | 451 | Ty::AssociatedType(type_alias, parameters) => { |
432 | let trait_ = match type_alias.lookup(f.db.upcast()).container { | 452 | let trait_ = match type_alias.lookup(f.db.upcast()).container { |
433 | AssocContainerId::TraitId(it) => it, | 453 | AssocContainerId::TraitId(it) => it, |
434 | _ => panic!("not an associated type"), | 454 | _ => panic!("not an associated type"), |
435 | }; | 455 | }; |
436 | let trait_ = f.db.trait_data(trait_); | 456 | let trait_ = f.db.trait_data(trait_); |
437 | let type_alias_data = f.db.type_alias_data(type_alias); | 457 | let type_alias_data = f.db.type_alias_data(*type_alias); |
438 | 458 | ||
439 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) | 459 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
440 | if f.display_target.is_test() { | 460 | if f.display_target.is_test() { |
441 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; | 461 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; |
442 | if self.parameters.len() > 0 { | 462 | if parameters.len() > 0 { |
443 | write!(f, "<")?; | 463 | write!(f, "<")?; |
444 | f.write_joined(&*self.parameters.0, ", ")?; | 464 | f.write_joined(&*parameters.0, ", ")?; |
445 | write!(f, ">")?; | 465 | write!(f, ">")?; |
446 | } | 466 | } |
447 | } else { | 467 | } else { |
448 | let projection_ty = ProjectionTy { | 468 | let projection_ty = |
449 | associated_ty: type_alias, | 469 | ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; |
450 | parameters: self.parameters.clone(), | ||
451 | }; | ||
452 | 470 | ||
453 | projection_ty.hir_fmt(f)?; | 471 | projection_ty.hir_fmt(f)?; |
454 | } | 472 | } |
455 | } | 473 | } |
456 | TypeCtor::ForeignType(type_alias) => { | 474 | Ty::ForeignType(type_alias) => { |
457 | let type_alias = f.db.type_alias_data(type_alias); | 475 | let type_alias = f.db.type_alias_data(*type_alias); |
458 | write!(f, "{}", type_alias.name)?; | 476 | write!(f, "{}", type_alias.name)?; |
459 | if self.parameters.len() > 0 { | ||
460 | write!(f, "<")?; | ||
461 | f.write_joined(&*self.parameters.0, ", ")?; | ||
462 | write!(f, ">")?; | ||
463 | } | ||
464 | } | 477 | } |
465 | TypeCtor::OpaqueType(opaque_ty_id) => { | 478 | Ty::OpaqueType(opaque_ty_id, parameters) => { |
466 | match opaque_ty_id { | 479 | match opaque_ty_id { |
467 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 480 | &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
468 | let datas = | 481 | let datas = |
469 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 482 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
470 | let data = (*datas) | 483 | let data = (*datas) |
471 | .as_ref() | 484 | .as_ref() |
472 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 485 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
473 | let bounds = data.subst(&self.parameters); | 486 | let bounds = data.subst(¶meters); |
474 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 487 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
475 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 488 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
476 | } | 489 | } |
477 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 490 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { |
478 | write!(f, "impl Future<Output = ")?; | 491 | write!(f, "impl Future<Output = ")?; |
479 | self.parameters[0].hir_fmt(f)?; | 492 | parameters[0].hir_fmt(f)?; |
480 | write!(f, ">")?; | 493 | write!(f, ">")?; |
481 | } | 494 | } |
482 | } | 495 | } |
483 | } | 496 | } |
484 | TypeCtor::Closure { .. } => { | 497 | Ty::Closure(.., substs) => { |
485 | let sig = self.parameters[0].callable_sig(f.db); | 498 | let sig = substs[0].callable_sig(f.db); |
486 | if let Some(sig) = sig { | 499 | if let Some(sig) = sig { |
487 | if sig.params().is_empty() { | 500 | if sig.params().is_empty() { |
488 | write!(f, "||")?; | 501 | write!(f, "||")?; |
@@ -505,43 +518,6 @@ impl HirDisplay for ApplicationTy { | |||
505 | write!(f, "{{closure}}")?; | 518 | write!(f, "{{closure}}")?; |
506 | } | 519 | } |
507 | } | 520 | } |
508 | } | ||
509 | Ok(()) | ||
510 | } | ||
511 | } | ||
512 | |||
513 | impl HirDisplay for ProjectionTy { | ||
514 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
515 | if f.should_truncate() { | ||
516 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
517 | } | ||
518 | |||
519 | let trait_ = f.db.trait_data(self.trait_(f.db)); | ||
520 | let first_parameter = self.parameters[0].into_displayable( | ||
521 | f.db, | ||
522 | f.max_size, | ||
523 | f.omit_verbose_types, | ||
524 | f.display_target, | ||
525 | ); | ||
526 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | ||
527 | if self.parameters.len() > 1 { | ||
528 | write!(f, "<")?; | ||
529 | f.write_joined(&self.parameters[1..], ", ")?; | ||
530 | write!(f, ">")?; | ||
531 | } | ||
532 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | ||
533 | Ok(()) | ||
534 | } | ||
535 | } | ||
536 | |||
537 | impl HirDisplay for Ty { | ||
538 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
539 | if f.should_truncate() { | ||
540 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
541 | } | ||
542 | |||
543 | match self { | ||
544 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | ||
545 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, | 521 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, |
546 | Ty::Placeholder(id) => { | 522 | Ty::Placeholder(id) => { |
547 | let generics = generics(f.db.upcast(), id.parent); | 523 | let generics = generics(f.db.upcast(), id.parent); |
@@ -595,7 +571,7 @@ impl HirDisplay for Ty { | |||
595 | } | 571 | } |
596 | } | 572 | } |
597 | 573 | ||
598 | impl HirDisplay for FnSig { | 574 | impl HirDisplay for CallableSig { |
599 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 575 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
600 | write!(f, "fn(")?; | 576 | write!(f, "fn(")?; |
601 | f.write_joined(self.params(), ", ")?; | 577 | f.write_joined(self.params(), ", ")?; |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 657f011d2..a1769729f 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -38,7 +38,7 @@ use syntax::SmolStr; | |||
38 | use super::{ | 38 | use super::{ |
39 | primitive::{FloatTy, IntTy}, | 39 | primitive::{FloatTy, IntTy}, |
40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 42 | }; |
43 | use crate::{ | 43 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar, |
@@ -46,15 +46,6 @@ use crate::{ | |||
46 | 46 | ||
47 | pub(crate) use unify::unify; | 47 | pub(crate) use unify::unify; |
48 | 48 | ||
49 | macro_rules! ty_app { | ||
50 | ($ctor:pat, $param:pat) => { | ||
51 | crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param }) | ||
52 | }; | ||
53 | ($ctor:pat) => { | ||
54 | ty_app!($ctor, _) | ||
55 | }; | ||
56 | } | ||
57 | |||
58 | mod unify; | 49 | mod unify; |
59 | mod path; | 50 | mod path; |
60 | mod expr; | 51 | mod expr; |
@@ -684,9 +675,9 @@ impl InferTy { | |||
684 | fn fallback_value(self) -> Ty { | 675 | fn fallback_value(self) -> Ty { |
685 | match self { | 676 | match self { |
686 | InferTy::TypeVar(..) => Ty::Unknown, | 677 | InferTy::TypeVar(..) => Ty::Unknown, |
687 | InferTy::IntVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), | 678 | InferTy::IntVar(..) => Ty::Scalar(Scalar::Int(IntTy::I32)), |
688 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), | 679 | InferTy::FloatVar(..) => Ty::Scalar(Scalar::Float(FloatTy::F64)), |
689 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), | 680 | InferTy::MaybeNeverTypeVar(..) => Ty::Never, |
690 | } | 681 | } |
691 | } | 682 | } |
692 | } | 683 | } |
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c7c57cd..4cca35904 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; |
8 | use test_utils::mark; | 8 | use test_utils::mark; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; | 10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; |
11 | 11 | ||
12 | use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; | 12 | use 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::Function { .. }) => 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::Function { .. }) => { |
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..23d4ac8ef 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, FnPointer, FnSig, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, |
22 | Scalar, Substs, TraitRef, Ty, TypeCtor, | 22 | Scalar, Substs, TraitRef, Ty, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | use super::{ | 25 | use 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(num_args, 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,12 @@ 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::Function(FnPointer { |
260 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 251 | num_args: sig_tys.len() - 1, |
261 | Substs(sig_tys.clone().into()), | 252 | sig: FnSig { variadic: false }, |
262 | ); | 253 | substs: Substs(sig_tys.clone().into()), |
263 | let closure_ty = | 254 | }); |
264 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); | 255 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); |
265 | 256 | ||
266 | // Eagerly try to relate the closure type with the expected | 257 | // Eagerly try to relate the closure type with the expected |
267 | // type, otherwise we often won't have enough information to | 258 | // type, otherwise we often won't have enough information to |
@@ -312,11 +303,8 @@ impl<'a> InferenceContext<'a> { | |||
312 | Expr::Match { expr, arms } => { | 303 | Expr::Match { expr, arms } => { |
313 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 304 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
314 | 305 | ||
315 | let mut result_ty = if arms.is_empty() { | 306 | let mut result_ty = |
316 | Ty::simple(TypeCtor::Never) | 307 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
317 | } else { | ||
318 | self.table.new_type_var() | ||
319 | }; | ||
320 | 308 | ||
321 | let matchee_diverges = self.diverges; | 309 | let matchee_diverges = self.diverges; |
322 | let mut all_arms_diverge = Diverges::Always; | 310 | let mut all_arms_diverge = Diverges::Always; |
@@ -327,7 +315,7 @@ impl<'a> InferenceContext<'a> { | |||
327 | if let Some(guard_expr) = arm.guard { | 315 | if let Some(guard_expr) = arm.guard { |
328 | self.infer_expr( | 316 | self.infer_expr( |
329 | guard_expr, | 317 | guard_expr, |
330 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | 318 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
331 | ); | 319 | ); |
332 | } | 320 | } |
333 | 321 | ||
@@ -345,7 +333,7 @@ impl<'a> InferenceContext<'a> { | |||
345 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 333 | 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) | 334 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
347 | } | 335 | } |
348 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 336 | Expr::Continue { .. } => Ty::Never, |
349 | Expr::Break { expr, label } => { | 337 | Expr::Break { expr, label } => { |
350 | let val_ty = if let Some(expr) = expr { | 338 | let val_ty = if let Some(expr) = expr { |
351 | self.infer_expr(*expr, &Expectation::none()) | 339 | self.infer_expr(*expr, &Expectation::none()) |
@@ -370,8 +358,7 @@ impl<'a> InferenceContext<'a> { | |||
370 | expr: tgt_expr, | 358 | expr: tgt_expr, |
371 | }); | 359 | }); |
372 | } | 360 | } |
373 | 361 | Ty::Never | |
374 | Ty::simple(TypeCtor::Never) | ||
375 | } | 362 | } |
376 | Expr::Return { expr } => { | 363 | Expr::Return { expr } => { |
377 | if let Some(expr) = expr { | 364 | if let Some(expr) = expr { |
@@ -380,14 +367,14 @@ impl<'a> InferenceContext<'a> { | |||
380 | let unit = Ty::unit(); | 367 | let unit = Ty::unit(); |
381 | self.coerce(&unit, &self.return_ty.clone()); | 368 | self.coerce(&unit, &self.return_ty.clone()); |
382 | } | 369 | } |
383 | Ty::simple(TypeCtor::Never) | 370 | Ty::Never |
384 | } | 371 | } |
385 | Expr::Yield { expr } => { | 372 | Expr::Yield { expr } => { |
386 | // FIXME: track yield type for coercion | 373 | // FIXME: track yield type for coercion |
387 | if let Some(expr) = expr { | 374 | if let Some(expr) = expr { |
388 | self.infer_expr(*expr, &Expectation::none()); | 375 | self.infer_expr(*expr, &Expectation::none()); |
389 | } | 376 | } |
390 | Ty::simple(TypeCtor::Never) | 377 | Ty::Never |
391 | } | 378 | } |
392 | Expr::RecordLit { path, fields, spread } => { | 379 | Expr::RecordLit { path, fields, spread } => { |
393 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 380 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -397,7 +384,7 @@ impl<'a> InferenceContext<'a> { | |||
397 | 384 | ||
398 | self.unify(&ty, &expected.ty); | 385 | self.unify(&ty, &expected.ty); |
399 | 386 | ||
400 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 387 | 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(); | 388 | 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)); | 389 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
403 | for (field_idx, field) in fields.iter().enumerate() { | 390 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -436,30 +423,23 @@ impl<'a> InferenceContext<'a> { | |||
436 | }, | 423 | }, |
437 | ) | 424 | ) |
438 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 425 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
439 | Ty::Apply(a_ty) => match a_ty.ctor { | 426 | Ty::Tuple(_, substs) => { |
440 | TypeCtor::Tuple { .. } => name | 427 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
441 | .as_tuple_index() | 428 | } |
442 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 429 | Ty::Adt(AdtId::StructId(s), parameters) => { |
443 | TypeCtor::Adt(AdtId::StructId(s)) => { | 430 | 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| { | 431 | let field = FieldId { parent: s.into(), local_id }; |
445 | let field = FieldId { parent: s.into(), local_id }; | 432 | self.write_field_resolution(tgt_expr, field); |
446 | self.write_field_resolution(tgt_expr, field); | 433 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
447 | self.db.field_types(s.into())[field.local_id] | 434 | }) |
448 | .clone() | 435 | } |
449 | .subst(&a_ty.parameters) | 436 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
450 | }) | 437 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
451 | } | 438 | let field = FieldId { parent: u.into(), local_id }; |
452 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 439 | self.write_field_resolution(tgt_expr, field); |
453 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 440 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) |
454 | let field = FieldId { parent: u.into(), local_id }; | 441 | }) |
455 | self.write_field_resolution(tgt_expr, field); | 442 | } |
456 | self.db.field_types(u.into())[field.local_id] | ||
457 | .clone() | ||
458 | .subst(&a_ty.parameters) | ||
459 | }) | ||
460 | } | ||
461 | _ => None, | ||
462 | }, | ||
463 | _ => None, | 443 | _ => None, |
464 | }) | 444 | }) |
465 | .unwrap_or(Ty::Unknown); | 445 | .unwrap_or(Ty::Unknown); |
@@ -497,19 +477,24 @@ impl<'a> InferenceContext<'a> { | |||
497 | Expectation::none() | 477 | Expectation::none() |
498 | }; | 478 | }; |
499 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 479 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
500 | let ty = match rawness { | 480 | match rawness { |
501 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 481 | Rawness::RawPtr => Ty::RawPtr(*mutability, Substs::single(inner_ty)), |
502 | Rawness::Ref => TypeCtor::Ref(*mutability), | 482 | Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)), |
503 | }; | 483 | } |
504 | Ty::apply_one(ty, inner_ty) | ||
505 | } | 484 | } |
506 | Expr::Box { expr } => { | 485 | Expr::Box { expr } => { |
507 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 486 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
508 | if let Some(box_) = self.resolve_boxed_box() { | 487 | if let Some(box_) = self.resolve_boxed_box() { |
509 | let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); | 488 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
510 | sb = sb.push(inner_ty); | 489 | sb = sb.push(inner_ty); |
490 | match self.db.generic_defaults(box_.into()).as_ref() { | ||
491 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | ||
492 | sb = sb.push(alloc_ty.value.clone()); | ||
493 | } | ||
494 | _ => (), | ||
495 | } | ||
511 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 496 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
512 | Ty::apply(TypeCtor::Adt(box_), sb.build()) | 497 | Ty::Adt(box_, sb.build()) |
513 | } else { | 498 | } else { |
514 | Ty::Unknown | 499 | Ty::Unknown |
515 | } | 500 | } |
@@ -539,14 +524,9 @@ impl<'a> InferenceContext<'a> { | |||
539 | UnaryOp::Neg => { | 524 | UnaryOp::Neg => { |
540 | match &inner_ty { | 525 | match &inner_ty { |
541 | // Fast path for builtins | 526 | // Fast path for builtins |
542 | Ty::Apply(ApplicationTy { | 527 | Ty::Scalar(Scalar::Int(_)) |
543 | ctor: TypeCtor::Scalar(Scalar::Int(_)), | 528 | | Ty::Scalar(Scalar::Uint(_)) |
544 | .. | 529 | | Ty::Scalar(Scalar::Float(_)) |
545 | }) | ||
546 | | Ty::Apply(ApplicationTy { | ||
547 | ctor: TypeCtor::Scalar(Scalar::Float(_)), | ||
548 | .. | ||
549 | }) | ||
550 | | Ty::Infer(InferTy::IntVar(..)) | 530 | | Ty::Infer(InferTy::IntVar(..)) |
551 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | 531 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, |
552 | // Otherwise we resolve via the std::ops::Neg trait | 532 | // Otherwise we resolve via the std::ops::Neg trait |
@@ -557,18 +537,9 @@ impl<'a> InferenceContext<'a> { | |||
557 | UnaryOp::Not => { | 537 | UnaryOp::Not => { |
558 | match &inner_ty { | 538 | match &inner_ty { |
559 | // Fast path for builtins | 539 | // Fast path for builtins |
560 | Ty::Apply(ApplicationTy { | 540 | Ty::Scalar(Scalar::Bool) |
561 | ctor: TypeCtor::Scalar(Scalar::Bool), | 541 | | Ty::Scalar(Scalar::Int(_)) |
562 | .. | 542 | | 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, | 543 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
573 | // Otherwise we resolve via the std::ops::Not trait | 544 | // Otherwise we resolve via the std::ops::Not trait |
574 | _ => self | 545 | _ => self |
@@ -580,9 +551,7 @@ impl<'a> InferenceContext<'a> { | |||
580 | Expr::BinaryOp { lhs, rhs, op } => match op { | 551 | Expr::BinaryOp { lhs, rhs, op } => match op { |
581 | Some(op) => { | 552 | Some(op) => { |
582 | let lhs_expectation = match op { | 553 | let lhs_expectation = match op { |
583 | BinaryOp::LogicOp(..) => { | 554 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
584 | Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))) | ||
585 | } | ||
586 | _ => Expectation::none(), | 555 | _ => Expectation::none(), |
587 | }; | 556 | }; |
588 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 557 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -613,31 +582,31 @@ impl<'a> InferenceContext<'a> { | |||
613 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 582 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
614 | match (range_type, lhs_ty, rhs_ty) { | 583 | match (range_type, lhs_ty, rhs_ty) { |
615 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 584 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
616 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 585 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
617 | None => Ty::Unknown, | 586 | None => Ty::Unknown, |
618 | }, | 587 | }, |
619 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 588 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
620 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 589 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
621 | None => Ty::Unknown, | 590 | None => Ty::Unknown, |
622 | }, | 591 | }, |
623 | (RangeOp::Inclusive, None, Some(ty)) => { | 592 | (RangeOp::Inclusive, None, Some(ty)) => { |
624 | match self.resolve_range_to_inclusive() { | 593 | match self.resolve_range_to_inclusive() { |
625 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 594 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
626 | None => Ty::Unknown, | 595 | None => Ty::Unknown, |
627 | } | 596 | } |
628 | } | 597 | } |
629 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 598 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
630 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 599 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
631 | None => Ty::Unknown, | 600 | None => Ty::Unknown, |
632 | }, | 601 | }, |
633 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 602 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
634 | match self.resolve_range_inclusive() { | 603 | match self.resolve_range_inclusive() { |
635 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 604 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
636 | None => Ty::Unknown, | 605 | None => Ty::Unknown, |
637 | } | 606 | } |
638 | } | 607 | } |
639 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 608 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
640 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 609 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
641 | None => Ty::Unknown, | 610 | None => Ty::Unknown, |
642 | }, | 611 | }, |
643 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 612 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -671,7 +640,7 @@ impl<'a> InferenceContext<'a> { | |||
671 | } | 640 | } |
672 | Expr::Tuple { exprs } => { | 641 | Expr::Tuple { exprs } => { |
673 | let mut tys = match &expected.ty { | 642 | let mut tys = match &expected.ty { |
674 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 643 | Ty::Tuple(_, substs) => substs |
675 | .iter() | 644 | .iter() |
676 | .cloned() | 645 | .cloned() |
677 | .chain(repeat_with(|| self.table.new_type_var())) | 646 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -684,15 +653,11 @@ impl<'a> InferenceContext<'a> { | |||
684 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 653 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
685 | } | 654 | } |
686 | 655 | ||
687 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 656 | Ty::Tuple(tys.len(), Substs(tys.into())) |
688 | } | 657 | } |
689 | Expr::Array(array) => { | 658 | Expr::Array(array) => { |
690 | let elem_ty = match &expected.ty { | 659 | let elem_ty = match &expected.ty { |
691 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 660 | 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(), | 661 | _ => self.table.new_type_var(), |
697 | }; | 662 | }; |
698 | 663 | ||
@@ -709,42 +674,38 @@ impl<'a> InferenceContext<'a> { | |||
709 | ); | 674 | ); |
710 | self.infer_expr( | 675 | self.infer_expr( |
711 | *repeat, | 676 | *repeat, |
712 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( | 677 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
713 | UintTy::Usize, | ||
714 | )))), | ||
715 | ); | 678 | ); |
716 | } | 679 | } |
717 | } | 680 | } |
718 | 681 | ||
719 | Ty::apply_one(TypeCtor::Array, elem_ty) | 682 | Ty::Array(Substs::single(elem_ty)) |
720 | } | 683 | } |
721 | Expr::Literal(lit) => match lit { | 684 | Expr::Literal(lit) => match lit { |
722 | Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), | 685 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
723 | Literal::String(..) => { | 686 | 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(..) => { | 687 | Literal::ByteString(..) => { |
727 | let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); | 688 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
728 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 689 | let array_type = Ty::Array(Substs::single(byte_type)); |
729 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 690 | Ty::Ref(Mutability::Shared, Substs::single(array_type)) |
730 | } | 691 | } |
731 | Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), | 692 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
732 | Literal::Int(_v, ty) => match ty { | 693 | Literal::Int(_v, ty) => match ty { |
733 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int( | 694 | Some(int_ty) => { |
734 | primitive::int_ty_from_builtin(*int_ty), | 695 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
735 | ))), | 696 | } |
736 | None => self.table.new_integer_var(), | 697 | None => self.table.new_integer_var(), |
737 | }, | 698 | }, |
738 | Literal::Uint(_v, ty) => match ty { | 699 | Literal::Uint(_v, ty) => match ty { |
739 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint( | 700 | Some(int_ty) => { |
740 | primitive::uint_ty_from_builtin(*int_ty), | 701 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
741 | ))), | 702 | } |
742 | None => self.table.new_integer_var(), | 703 | None => self.table.new_integer_var(), |
743 | }, | 704 | }, |
744 | Literal::Float(_v, ty) => match ty { | 705 | Literal::Float(_v, ty) => match ty { |
745 | Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float( | 706 | Some(float_ty) => { |
746 | primitive::float_ty_from_builtin(*float_ty), | 707 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
747 | ))), | 708 | } |
748 | None => self.table.new_float_var(), | 709 | None => self.table.new_float_var(), |
749 | }, | 710 | }, |
750 | }, | 711 | }, |
@@ -857,7 +818,7 @@ impl<'a> InferenceContext<'a> { | |||
857 | // Apply autoref so the below unification works correctly | 818 | // Apply autoref so the below unification works correctly |
858 | // FIXME: return correct autorefs from lookup_method | 819 | // FIXME: return correct autorefs from lookup_method |
859 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 820 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
860 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 821 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
861 | _ => derefed_receiver_ty, | 822 | _ => derefed_receiver_ty, |
862 | }; | 823 | }; |
863 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 824 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -934,30 +895,26 @@ impl<'a> InferenceContext<'a> { | |||
934 | } | 895 | } |
935 | 896 | ||
936 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 897 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
937 | if let Ty::Apply(a_ty) = callable_ty { | 898 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
938 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 899 | let generic_predicates = self.db.generic_predicates(def.into()); |
939 | let generic_predicates = self.db.generic_predicates(def.into()); | 900 | for predicate in generic_predicates.iter() { |
940 | for predicate in generic_predicates.iter() { | 901 | let predicate = predicate.clone().subst(parameters); |
941 | let predicate = predicate.clone().subst(&a_ty.parameters); | 902 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
942 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 903 | self.obligations.push(obligation); |
943 | self.obligations.push(obligation); | ||
944 | } | ||
945 | } | 904 | } |
946 | // add obligation for trait implementation, if this is a trait method | 905 | } |
947 | match def { | 906 | // add obligation for trait implementation, if this is a trait method |
948 | CallableDefId::FunctionId(f) => { | 907 | match def { |
949 | if let AssocContainerId::TraitId(trait_) = | 908 | CallableDefId::FunctionId(f) => { |
950 | f.lookup(self.db.upcast()).container | 909 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
951 | { | 910 | { |
952 | // construct a TraitDef | 911 | // construct a TraitDef |
953 | let substs = a_ty | 912 | let substs = |
954 | .parameters | 913 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
955 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 914 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
956 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
957 | } | ||
958 | } | 915 | } |
959 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
960 | } | 916 | } |
917 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
961 | } | 918 | } |
962 | } | 919 | } |
963 | } | 920 | } |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index d974f805b..a318e47f3 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; | |||
13 | use test_utils::mark; | 13 | use test_utils::mark; |
14 | 14 | ||
15 | use super::{BindingMode, Expectation, InferenceContext}; | 15 | use super::{BindingMode, Expectation, InferenceContext}; |
16 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; | 16 | use crate::{utils::variant_data, Substs, Ty}; |
17 | 17 | ||
18 | impl<'a> InferenceContext<'a> { | 18 | impl<'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(inner_tys.len(), 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; | |||
9 | use super::{InferenceContext, Obligation}; | 9 | use super::{InferenceContext, Obligation}; |
10 | use crate::{ | 10 | use 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 | ||
15 | impl<'a> InferenceContext<'a> { | 15 | impl<'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 |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 676519594..1abb0440f 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -25,7 +25,7 @@ mod test_db; | |||
25 | 25 | ||
26 | use std::{iter, mem, ops::Deref, sync::Arc}; | 26 | use std::{iter, mem, ops::Deref, sync::Arc}; |
27 | 27 | ||
28 | use base_db::{salsa, CrateId}; | 28 | use base_db::salsa; |
29 | use hir_def::{ | 29 | use hir_def::{ |
30 | builtin_type::BuiltinType, | 30 | builtin_type::BuiltinType, |
31 | expr::ExprId, | 31 | expr::ExprId, |
@@ -57,192 +57,6 @@ pub enum Lifetime { | |||
57 | Static, | 57 | Static, |
58 | } | 58 | } |
59 | 59 | ||
60 | /// A type constructor or type name: this might be something like the primitive | ||
61 | /// type `bool`, a struct like `Vec`, or things like function pointers or | ||
62 | /// tuples. | ||
63 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | ||
64 | pub enum TypeCtor { | ||
65 | /// a scalar type like `bool` or `u32` | ||
66 | Scalar(Scalar), | ||
67 | |||
68 | /// Structures, enumerations and unions. | ||
69 | Adt(AdtId), | ||
70 | |||
71 | /// The pointee of a string slice. Written as `str`. | ||
72 | Str, | ||
73 | |||
74 | /// The pointee of an array slice. Written as `[T]`. | ||
75 | Slice, | ||
76 | |||
77 | /// An array with the given length. Written as `[T; n]`. | ||
78 | Array, | ||
79 | |||
80 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
81 | RawPtr(Mutability), | ||
82 | |||
83 | /// A reference; a pointer with an associated lifetime. Written as | ||
84 | /// `&'a mut T` or `&'a T`. | ||
85 | Ref(Mutability), | ||
86 | |||
87 | /// The anonymous type of a function declaration/definition. Each | ||
88 | /// function has a unique type, which is output (for a function | ||
89 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
90 | /// | ||
91 | /// This includes tuple struct / enum variant constructors as well. | ||
92 | /// | ||
93 | /// For example the type of `bar` here: | ||
94 | /// | ||
95 | /// ``` | ||
96 | /// fn foo() -> i32 { 1 } | ||
97 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
98 | /// ``` | ||
99 | FnDef(CallableDefId), | ||
100 | |||
101 | /// A pointer to a function. Written as `fn() -> i32`. | ||
102 | /// | ||
103 | /// For example the type of `bar` here: | ||
104 | /// | ||
105 | /// ``` | ||
106 | /// fn foo() -> i32 { 1 } | ||
107 | /// let bar: fn() -> i32 = foo; | ||
108 | /// ``` | ||
109 | // FIXME make this a Ty variant like in Chalk | ||
110 | FnPtr { num_args: u16, is_varargs: bool }, | ||
111 | |||
112 | /// The never type `!`. | ||
113 | Never, | ||
114 | |||
115 | /// A tuple type. For example, `(i32, bool)`. | ||
116 | Tuple { cardinality: u16 }, | ||
117 | |||
118 | /// Represents an associated item like `Iterator::Item`. This is used | ||
119 | /// when we have tried to normalize a projection like `T::Item` but | ||
120 | /// couldn't find a better representation. In that case, we generate | ||
121 | /// an **application type** like `(Iterator::Item)<T>`. | ||
122 | AssociatedType(TypeAliasId), | ||
123 | |||
124 | /// This represents a placeholder for an opaque type in situations where we | ||
125 | /// don't know the hidden type (i.e. currently almost always). This is | ||
126 | /// analogous to the `AssociatedType` type constructor. | ||
127 | /// It is also used as the type of async block, with one type parameter | ||
128 | /// representing the Future::Output type. | ||
129 | OpaqueType(OpaqueTyId), | ||
130 | |||
131 | /// Represents a foreign type declared in external blocks. | ||
132 | ForeignType(TypeAliasId), | ||
133 | |||
134 | /// The type of a specific closure. | ||
135 | /// | ||
136 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
137 | /// parameter. | ||
138 | Closure { def: DefWithBodyId, expr: ExprId }, | ||
139 | } | ||
140 | |||
141 | impl TypeCtor { | ||
142 | pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { | ||
143 | match self { | ||
144 | TypeCtor::Scalar(_) | ||
145 | | TypeCtor::Str | ||
146 | | TypeCtor::Never => 0, | ||
147 | TypeCtor::Slice | ||
148 | | TypeCtor::Array | ||
149 | | TypeCtor::RawPtr(_) | ||
150 | | TypeCtor::Ref(_) | ||
151 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | ||
152 | => 1, | ||
153 | TypeCtor::Adt(adt) => { | ||
154 | let generic_params = generics(db.upcast(), adt.into()); | ||
155 | generic_params.len() | ||
156 | } | ||
157 | TypeCtor::FnDef(callable) => { | ||
158 | let generic_params = generics(db.upcast(), callable.into()); | ||
159 | generic_params.len() | ||
160 | } | ||
161 | TypeCtor::AssociatedType(type_alias) => { | ||
162 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
163 | generic_params.len() | ||
164 | } | ||
165 | TypeCtor::ForeignType(type_alias) => { | ||
166 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
167 | generic_params.len() | ||
168 | } | ||
169 | TypeCtor::OpaqueType(opaque_ty_id) => { | ||
170 | match opaque_ty_id { | ||
171 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
172 | let generic_params = generics(db.upcast(), func.into()); | ||
173 | generic_params.len() | ||
174 | } | ||
175 | // 1 param representing Future::Output type. | ||
176 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
177 | } | ||
178 | } | ||
179 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | ||
180 | TypeCtor::Tuple { cardinality } => cardinality as usize, | ||
181 | } | ||
182 | } | ||
183 | |||
184 | pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> { | ||
185 | match self { | ||
186 | TypeCtor::Scalar(_) | ||
187 | | TypeCtor::Str | ||
188 | | TypeCtor::Never | ||
189 | | TypeCtor::Slice | ||
190 | | TypeCtor::Array | ||
191 | | TypeCtor::RawPtr(_) | ||
192 | | TypeCtor::Ref(_) | ||
193 | | TypeCtor::FnPtr { .. } | ||
194 | | TypeCtor::Tuple { .. } => None, | ||
195 | // Closure's krate is irrelevant for coherence I would think? | ||
196 | TypeCtor::Closure { .. } => None, | ||
197 | TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()), | ||
198 | TypeCtor::FnDef(callable) => Some(callable.krate(db)), | ||
199 | TypeCtor::AssociatedType(type_alias) => { | ||
200 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
201 | } | ||
202 | TypeCtor::ForeignType(type_alias) => { | ||
203 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
204 | } | ||
205 | TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { | ||
206 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
207 | Some(func.lookup(db.upcast()).module(db.upcast()).krate()) | ||
208 | } | ||
209 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => { | ||
210 | Some(def.module(db.upcast()).krate()) | ||
211 | } | ||
212 | }, | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pub fn as_generic_def(self) -> Option<GenericDefId> { | ||
217 | match self { | ||
218 | TypeCtor::Scalar(_) | ||
219 | | TypeCtor::Str | ||
220 | | TypeCtor::Never | ||
221 | | TypeCtor::Slice | ||
222 | | TypeCtor::Array | ||
223 | | TypeCtor::RawPtr(_) | ||
224 | | TypeCtor::Ref(_) | ||
225 | | TypeCtor::FnPtr { .. } | ||
226 | | TypeCtor::Tuple { .. } | ||
227 | | TypeCtor::Closure { .. } => None, | ||
228 | TypeCtor::Adt(adt) => Some(adt.into()), | ||
229 | TypeCtor::FnDef(callable) => Some(callable.into()), | ||
230 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | ||
231 | TypeCtor::ForeignType(type_alias) => Some(type_alias.into()), | ||
232 | TypeCtor::OpaqueType(_impl_trait_id) => None, | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
238 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
239 | /// several other things. | ||
240 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
241 | pub struct ApplicationTy { | ||
242 | pub ctor: TypeCtor, | ||
243 | pub parameters: Substs, | ||
244 | } | ||
245 | |||
246 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
247 | pub struct OpaqueTy { | 61 | pub struct OpaqueTy { |
248 | pub opaque_ty_id: OpaqueTyId, | 62 | pub opaque_ty_id: OpaqueTyId, |
@@ -285,6 +99,18 @@ impl TypeWalk for ProjectionTy { | |||
285 | } | 99 | } |
286 | } | 100 | } |
287 | 101 | ||
102 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
103 | pub struct FnSig { | ||
104 | pub variadic: bool, | ||
105 | } | ||
106 | |||
107 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
108 | pub struct FnPointer { | ||
109 | pub num_args: usize, | ||
110 | pub sig: FnSig, | ||
111 | pub substs: Substs, | ||
112 | } | ||
113 | |||
288 | /// A type. | 114 | /// A type. |
289 | /// | 115 | /// |
290 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 116 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents |
@@ -293,10 +119,79 @@ impl TypeWalk for ProjectionTy { | |||
293 | /// This should be cheap to clone. | 119 | /// This should be cheap to clone. |
294 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 120 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
295 | pub enum Ty { | 121 | pub enum Ty { |
296 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | 122 | /// Structures, enumerations and unions. |
297 | /// type like `bool`, a struct, tuple, function pointer, reference or | 123 | Adt(AdtId, Substs), |
298 | /// several other things. | 124 | |
299 | Apply(ApplicationTy), | 125 | /// Represents an associated item like `Iterator::Item`. This is used |
126 | /// when we have tried to normalize a projection like `T::Item` but | ||
127 | /// couldn't find a better representation. In that case, we generate | ||
128 | /// an **application type** like `(Iterator::Item)<T>`. | ||
129 | AssociatedType(TypeAliasId, Substs), | ||
130 | |||
131 | /// a scalar type like `bool` or `u32` | ||
132 | Scalar(Scalar), | ||
133 | |||
134 | /// A tuple type. For example, `(i32, bool)`. | ||
135 | Tuple(usize, Substs), | ||
136 | |||
137 | /// An array with the given length. Written as `[T; n]`. | ||
138 | Array(Substs), | ||
139 | |||
140 | /// The pointee of an array slice. Written as `[T]`. | ||
141 | Slice(Substs), | ||
142 | |||
143 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
144 | RawPtr(Mutability, Substs), | ||
145 | |||
146 | /// A reference; a pointer with an associated lifetime. Written as | ||
147 | /// `&'a mut T` or `&'a T`. | ||
148 | Ref(Mutability, Substs), | ||
149 | |||
150 | /// This represents a placeholder for an opaque type in situations where we | ||
151 | /// don't know the hidden type (i.e. currently almost always). This is | ||
152 | /// analogous to the `AssociatedType` type constructor. | ||
153 | /// It is also used as the type of async block, with one type parameter | ||
154 | /// representing the Future::Output type. | ||
155 | OpaqueType(OpaqueTyId, Substs), | ||
156 | |||
157 | /// The anonymous type of a function declaration/definition. Each | ||
158 | /// function has a unique type, which is output (for a function | ||
159 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
160 | /// | ||
161 | /// This includes tuple struct / enum variant constructors as well. | ||
162 | /// | ||
163 | /// For example the type of `bar` here: | ||
164 | /// | ||
165 | /// ``` | ||
166 | /// fn foo() -> i32 { 1 } | ||
167 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
168 | /// ``` | ||
169 | FnDef(CallableDefId, Substs), | ||
170 | |||
171 | /// The pointee of a string slice. Written as `str`. | ||
172 | Str, | ||
173 | |||
174 | /// The never type `!`. | ||
175 | Never, | ||
176 | |||
177 | /// The type of a specific closure. | ||
178 | /// | ||
179 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
180 | /// parameter. | ||
181 | Closure(DefWithBodyId, ExprId, Substs), | ||
182 | |||
183 | /// Represents a foreign type declared in external blocks. | ||
184 | ForeignType(TypeAliasId), | ||
185 | |||
186 | /// A pointer to a function. Written as `fn() -> i32`. | ||
187 | /// | ||
188 | /// For example the type of `bar` here: | ||
189 | /// | ||
190 | /// ``` | ||
191 | /// fn foo() -> i32 { 1 } | ||
192 | /// let bar: fn() -> i32 = foo; | ||
193 | /// ``` | ||
194 | Function(FnPointer), | ||
300 | 195 | ||
301 | /// A "projection" type corresponds to an (unnormalized) | 196 | /// A "projection" type corresponds to an (unnormalized) |
302 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 197 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
@@ -420,10 +315,6 @@ impl Substs { | |||
420 | Substs::builder(generic_params.len()) | 315 | Substs::builder(generic_params.len()) |
421 | } | 316 | } |
422 | 317 | ||
423 | pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { | ||
424 | Substs::builder(type_ctor.num_ty_params(db)) | ||
425 | } | ||
426 | |||
427 | fn builder(param_count: usize) -> SubstsBuilder { | 318 | fn builder(param_count: usize) -> SubstsBuilder { |
428 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | 319 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } |
429 | } | 320 | } |
@@ -655,22 +546,29 @@ pub enum TyKind { | |||
655 | /// A function signature as seen by type inference: Several parameter types and | 546 | /// A function signature as seen by type inference: Several parameter types and |
656 | /// one return type. | 547 | /// one return type. |
657 | #[derive(Clone, PartialEq, Eq, Debug)] | 548 | #[derive(Clone, PartialEq, Eq, Debug)] |
658 | pub struct FnSig { | 549 | pub struct CallableSig { |
659 | params_and_return: Arc<[Ty]>, | 550 | params_and_return: Arc<[Ty]>, |
660 | is_varargs: bool, | 551 | is_varargs: bool, |
661 | } | 552 | } |
662 | 553 | ||
663 | /// A polymorphic function signature. | 554 | /// A polymorphic function signature. |
664 | pub type PolyFnSig = Binders<FnSig>; | 555 | pub type PolyFnSig = Binders<CallableSig>; |
665 | 556 | ||
666 | impl FnSig { | 557 | impl CallableSig { |
667 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { | 558 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig { |
668 | params.push(ret); | 559 | params.push(ret); |
669 | FnSig { params_and_return: params.into(), is_varargs } | 560 | CallableSig { params_and_return: params.into(), is_varargs } |
670 | } | 561 | } |
671 | 562 | ||
672 | pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { | 563 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { |
673 | FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } | 564 | CallableSig { |
565 | params_and_return: Arc::clone(&fn_ptr.substs.0), | ||
566 | is_varargs: fn_ptr.sig.variadic, | ||
567 | } | ||
568 | } | ||
569 | |||
570 | pub fn from_substs(substs: &Substs) -> CallableSig { | ||
571 | CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } | ||
674 | } | 572 | } |
675 | 573 | ||
676 | pub fn params(&self) -> &[Ty] { | 574 | pub fn params(&self) -> &[Ty] { |
@@ -682,7 +580,7 @@ impl FnSig { | |||
682 | } | 580 | } |
683 | } | 581 | } |
684 | 582 | ||
685 | impl TypeWalk for FnSig { | 583 | impl TypeWalk for CallableSig { |
686 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 584 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
687 | for t in self.params_and_return.iter() { | 585 | for t in self.params_and_return.iter() { |
688 | t.walk(f); | 586 | t.walk(f); |
@@ -701,54 +599,42 @@ impl TypeWalk for FnSig { | |||
701 | } | 599 | } |
702 | 600 | ||
703 | impl Ty { | 601 | impl Ty { |
704 | pub fn simple(ctor: TypeCtor) -> Ty { | ||
705 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) | ||
706 | } | ||
707 | pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { | ||
708 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) | ||
709 | } | ||
710 | pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { | ||
711 | Ty::Apply(ApplicationTy { ctor, parameters }) | ||
712 | } | ||
713 | pub fn unit() -> Self { | 602 | pub fn unit() -> Self { |
714 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 603 | Ty::Tuple(0, Substs::empty()) |
715 | } | 604 | } |
716 | pub fn fn_ptr(sig: FnSig) -> Self { | 605 | |
717 | Ty::apply( | 606 | pub fn fn_ptr(sig: CallableSig) -> Self { |
718 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, | 607 | Ty::Function(FnPointer { |
719 | Substs(sig.params_and_return), | 608 | num_args: sig.params().len(), |
720 | ) | 609 | sig: FnSig { variadic: sig.is_varargs }, |
610 | substs: Substs(sig.params_and_return), | ||
611 | }) | ||
721 | } | 612 | } |
613 | |||
722 | pub fn builtin(builtin: BuiltinType) -> Self { | 614 | pub fn builtin(builtin: BuiltinType) -> Self { |
723 | Ty::simple(match builtin { | 615 | match builtin { |
724 | BuiltinType::Char => TypeCtor::Scalar(Scalar::Char), | 616 | BuiltinType::Char => Ty::Scalar(Scalar::Char), |
725 | BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool), | 617 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), |
726 | BuiltinType::Str => TypeCtor::Str, | 618 | BuiltinType::Str => Ty::Str, |
727 | BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), | 619 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), |
728 | BuiltinType::Uint(t) => { | 620 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), |
729 | TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))) | 621 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), |
730 | } | 622 | } |
731 | BuiltinType::Float(t) => { | ||
732 | TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))) | ||
733 | } | ||
734 | }) | ||
735 | } | 623 | } |
736 | 624 | ||
737 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 625 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
738 | match self { | 626 | match self { |
739 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 627 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), |
740 | Some((parameters.as_single(), *mutability)) | ||
741 | } | ||
742 | _ => None, | 628 | _ => None, |
743 | } | 629 | } |
744 | } | 630 | } |
745 | 631 | ||
746 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 632 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
747 | match self { | 633 | match self { |
748 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 634 | Ty::Ref(mutability, parameters) => { |
749 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 635 | Some((parameters.as_single(), Rawness::Ref, *mutability)) |
750 | } | 636 | } |
751 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | 637 | Ty::RawPtr(mutability, parameters) => { |
752 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | 638 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) |
753 | } | 639 | } |
754 | _ => None, | 640 | _ => None, |
@@ -758,7 +644,7 @@ impl Ty { | |||
758 | pub fn strip_references(&self) -> &Ty { | 644 | pub fn strip_references(&self) -> &Ty { |
759 | let mut t: &Ty = self; | 645 | let mut t: &Ty = self; |
760 | 646 | ||
761 | while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { | 647 | while let Ty::Ref(_mutability, parameters) = t { |
762 | t = parameters.as_single(); | 648 | t = parameters.as_single(); |
763 | } | 649 | } |
764 | 650 | ||
@@ -767,30 +653,62 @@ impl Ty { | |||
767 | 653 | ||
768 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { | 654 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { |
769 | match self { | 655 | match self { |
770 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 656 | Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)), |
771 | Some((*adt_def, parameters)) | ||
772 | } | ||
773 | _ => None, | 657 | _ => None, |
774 | } | 658 | } |
775 | } | 659 | } |
776 | 660 | ||
777 | pub fn as_tuple(&self) -> Option<&Substs> { | 661 | pub fn as_tuple(&self) -> Option<&Substs> { |
778 | match self { | 662 | match self { |
779 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | 663 | Ty::Tuple(_, substs) => Some(substs), |
780 | Some(parameters) | 664 | _ => None, |
781 | } | 665 | } |
666 | } | ||
667 | |||
668 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | ||
669 | match *self { | ||
670 | Ty::Adt(adt, ..) => Some(adt.into()), | ||
671 | Ty::FnDef(callable, ..) => Some(callable.into()), | ||
672 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | ||
673 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | ||
782 | _ => None, | 674 | _ => None, |
783 | } | 675 | } |
784 | } | 676 | } |
785 | 677 | ||
786 | pub fn is_never(&self) -> bool { | 678 | pub fn is_never(&self) -> bool { |
787 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 679 | matches!(self, Ty::Never) |
788 | } | 680 | } |
789 | 681 | ||
790 | pub fn is_unknown(&self) -> bool { | 682 | pub fn is_unknown(&self) -> bool { |
791 | matches!(self, Ty::Unknown) | 683 | matches!(self, Ty::Unknown) |
792 | } | 684 | } |
793 | 685 | ||
686 | pub fn equals_ctor(&self, other: &Ty) -> bool { | ||
687 | match (self, other) { | ||
688 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | ||
689 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | ||
690 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | ||
691 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | ||
692 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | ||
693 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | ||
694 | (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { | ||
695 | expr == expr2 && def == def2 | ||
696 | } | ||
697 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
698 | | (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => { | ||
699 | mutability == mutability2 | ||
700 | } | ||
701 | ( | ||
702 | Ty::Function(FnPointer { num_args, sig, .. }), | ||
703 | Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), | ||
704 | ) => num_args == num_args2 && sig == sig2, | ||
705 | (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, | ||
706 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | ||
707 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | ||
708 | _ => false, | ||
709 | } | ||
710 | } | ||
711 | |||
794 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 712 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
795 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 713 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
796 | match self { | 714 | match self { |
@@ -809,41 +727,30 @@ impl Ty { | |||
809 | 727 | ||
810 | fn builtin_deref(&self) -> Option<Ty> { | 728 | fn builtin_deref(&self) -> Option<Ty> { |
811 | match self { | 729 | match self { |
812 | Ty::Apply(a_ty) => match a_ty.ctor { | 730 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), |
813 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 731 | Ty::RawPtr(.., parameters) => Some(Ty::clone(parameters.as_single())), |
814 | TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), | ||
815 | _ => None, | ||
816 | }, | ||
817 | _ => None, | 732 | _ => None, |
818 | } | 733 | } |
819 | } | 734 | } |
820 | 735 | ||
821 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 736 | pub fn as_fn_def(&self) -> Option<FunctionId> { |
822 | match self { | 737 | match self { |
823 | &Ty::Apply(ApplicationTy { | 738 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), |
824 | ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), | ||
825 | .. | ||
826 | }) => Some(func), | ||
827 | _ => None, | 739 | _ => None, |
828 | } | 740 | } |
829 | } | 741 | } |
830 | 742 | ||
831 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 743 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { |
832 | match self { | 744 | match self { |
833 | Ty::Apply(a_ty) => match a_ty.ctor { | 745 | Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), |
834 | TypeCtor::FnPtr { is_varargs, .. } => { | 746 | Ty::FnDef(def, parameters) => { |
835 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | 747 | let sig = db.callable_item_signature(*def); |
836 | } | 748 | Some(sig.subst(¶meters)) |
837 | TypeCtor::FnDef(def) => { | 749 | } |
838 | let sig = db.callable_item_signature(def); | 750 | Ty::Closure(.., substs) => { |
839 | Some(sig.subst(&a_ty.parameters)) | 751 | let sig_param = &substs[0]; |
840 | } | 752 | sig_param.callable_sig(db) |
841 | TypeCtor::Closure { .. } => { | 753 | } |
842 | let sig_param = &a_ty.parameters[0]; | ||
843 | sig_param.callable_sig(db) | ||
844 | } | ||
845 | _ => None, | ||
846 | }, | ||
847 | _ => None, | 754 | _ => None, |
848 | } | 755 | } |
849 | } | 756 | } |
@@ -852,28 +759,66 @@ impl Ty { | |||
852 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | 759 | /// the `Substs` for these type parameters with the given ones. (So e.g. if |
853 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 760 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
854 | /// `Option<u32>` afterwards.) | 761 | /// `Option<u32>` afterwards.) |
855 | pub fn apply_substs(self, substs: Substs) -> Ty { | 762 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
856 | match self { | 763 | match &mut self { |
857 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | 764 | Ty::Adt(_, substs) |
858 | assert_eq!(previous_substs.len(), substs.len()); | 765 | | Ty::Slice(substs) |
859 | Ty::Apply(ApplicationTy { ctor, parameters: substs }) | 766 | | Ty::Array(substs) |
767 | | Ty::RawPtr(_, substs) | ||
768 | | Ty::Ref(_, substs) | ||
769 | | Ty::FnDef(_, substs) | ||
770 | | Ty::Function(FnPointer { substs, .. }) | ||
771 | | Ty::Tuple(_, substs) | ||
772 | | Ty::OpaqueType(_, substs) | ||
773 | | Ty::AssociatedType(_, substs) | ||
774 | | Ty::Closure(.., substs) => { | ||
775 | assert_eq!(substs.len(), new_substs.len()); | ||
776 | *substs = new_substs; | ||
860 | } | 777 | } |
861 | _ => self, | 778 | _ => (), |
862 | } | 779 | } |
780 | self | ||
863 | } | 781 | } |
864 | 782 | ||
865 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 783 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
866 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 784 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
867 | pub fn substs(&self) -> Option<Substs> { | 785 | pub fn substs(&self) -> Option<&Substs> { |
868 | match self { | 786 | match self { |
869 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | 787 | Ty::Adt(_, substs) |
788 | | Ty::Slice(substs) | ||
789 | | Ty::Array(substs) | ||
790 | | Ty::RawPtr(_, substs) | ||
791 | | Ty::Ref(_, substs) | ||
792 | | Ty::FnDef(_, substs) | ||
793 | | Ty::Function(FnPointer { substs, .. }) | ||
794 | | Ty::Tuple(_, substs) | ||
795 | | Ty::OpaqueType(_, substs) | ||
796 | | Ty::AssociatedType(_, substs) | ||
797 | | Ty::Closure(.., substs) => Some(substs), | ||
798 | _ => None, | ||
799 | } | ||
800 | } | ||
801 | |||
802 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | ||
803 | match self { | ||
804 | Ty::Adt(_, substs) | ||
805 | | Ty::Slice(substs) | ||
806 | | Ty::Array(substs) | ||
807 | | Ty::RawPtr(_, substs) | ||
808 | | Ty::Ref(_, substs) | ||
809 | | Ty::FnDef(_, substs) | ||
810 | | Ty::Function(FnPointer { substs, .. }) | ||
811 | | Ty::Tuple(_, substs) | ||
812 | | Ty::OpaqueType(_, substs) | ||
813 | | Ty::AssociatedType(_, substs) | ||
814 | | Ty::Closure(.., substs) => Some(substs), | ||
870 | _ => None, | 815 | _ => None, |
871 | } | 816 | } |
872 | } | 817 | } |
873 | 818 | ||
874 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 819 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
875 | match self { | 820 | match self { |
876 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | 821 | Ty::OpaqueType(opaque_ty_id, ..) => { |
877 | match opaque_ty_id { | 822 | match opaque_ty_id { |
878 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 823 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { |
879 | let krate = def.module(db.upcast()).krate(); | 824 | let krate = def.module(db.upcast()).krate(); |
@@ -934,7 +879,7 @@ impl Ty { | |||
934 | 879 | ||
935 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 880 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
936 | match self { | 881 | match self { |
937 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | 882 | Ty::AssociatedType(type_alias_id, ..) => { |
938 | match type_alias_id.lookup(db.upcast()).container { | 883 | match type_alias_id.lookup(db.upcast()).container { |
939 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 884 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
940 | _ => None, | 885 | _ => None, |
@@ -1049,11 +994,6 @@ pub trait TypeWalk { | |||
1049 | impl TypeWalk for Ty { | 994 | impl TypeWalk for Ty { |
1050 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 995 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
1051 | match self { | 996 | match self { |
1052 | Ty::Apply(a_ty) => { | ||
1053 | for t in a_ty.parameters.iter() { | ||
1054 | t.walk(f); | ||
1055 | } | ||
1056 | } | ||
1057 | Ty::Projection(p_ty) => { | 997 | Ty::Projection(p_ty) => { |
1058 | for t in p_ty.parameters.iter() { | 998 | for t in p_ty.parameters.iter() { |
1059 | t.walk(f); | 999 | t.walk(f); |
@@ -1069,7 +1009,13 @@ impl TypeWalk for Ty { | |||
1069 | t.walk(f); | 1009 | t.walk(f); |
1070 | } | 1010 | } |
1071 | } | 1011 | } |
1072 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1012 | _ => { |
1013 | if let Some(substs) = self.substs() { | ||
1014 | for t in substs.iter() { | ||
1015 | t.walk(f); | ||
1016 | } | ||
1017 | } | ||
1018 | } | ||
1073 | } | 1019 | } |
1074 | f(self); | 1020 | f(self); |
1075 | } | 1021 | } |
@@ -1080,9 +1026,6 @@ impl TypeWalk for Ty { | |||
1080 | binders: DebruijnIndex, | 1026 | binders: DebruijnIndex, |
1081 | ) { | 1027 | ) { |
1082 | match self { | 1028 | match self { |
1083 | Ty::Apply(a_ty) => { | ||
1084 | a_ty.parameters.walk_mut_binders(f, binders); | ||
1085 | } | ||
1086 | Ty::Projection(p_ty) => { | 1029 | Ty::Projection(p_ty) => { |
1087 | p_ty.parameters.walk_mut_binders(f, binders); | 1030 | p_ty.parameters.walk_mut_binders(f, binders); |
1088 | } | 1031 | } |
@@ -1094,7 +1037,11 @@ impl TypeWalk for Ty { | |||
1094 | Ty::Opaque(o_ty) => { | 1037 | Ty::Opaque(o_ty) => { |
1095 | o_ty.parameters.walk_mut_binders(f, binders); | 1038 | o_ty.parameters.walk_mut_binders(f, binders); |
1096 | } | 1039 | } |
1097 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1040 | _ => { |
1041 | if let Some(substs) = self.substs_mut() { | ||
1042 | substs.walk_mut_binders(f, binders); | ||
1043 | } | ||
1044 | } | ||
1098 | } | 1045 | } |
1099 | f(self, binders); | 1046 | f(self, binders); |
1100 | } | 1047 | } |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 99b0ecf3b..44bd95a9a 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -31,9 +31,9 @@ use crate::{ | |||
31 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 31 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
32 | make_mut_slice, variant_data, | 32 | make_mut_slice, variant_data, |
33 | }, | 33 | }, |
34 | Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, | 34 | Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, OpaqueTy, |
35 | ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, | 35 | OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, |
36 | TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 36 | ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #[derive(Debug)] | 39 | #[derive(Debug)] |
@@ -145,13 +145,10 @@ impl Ty { | |||
145 | pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { | 145 | pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { |
146 | let mut res = None; | 146 | let mut res = None; |
147 | let ty = match type_ref { | 147 | let ty = match type_ref { |
148 | TypeRef::Never => Ty::simple(TypeCtor::Never), | 148 | TypeRef::Never => Ty::Never, |
149 | TypeRef::Tuple(inner) => { | 149 | TypeRef::Tuple(inner) => { |
150 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); | 150 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); |
151 | Ty::apply( | 151 | Ty::Tuple(inner_tys.len(), Substs(inner_tys)) |
152 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | ||
153 | Substs(inner_tys), | ||
154 | ) | ||
155 | } | 152 | } |
156 | TypeRef::Path(path) => { | 153 | TypeRef::Path(path) => { |
157 | let (ty, res_) = Ty::from_hir_path(ctx, path); | 154 | let (ty, res_) = Ty::from_hir_path(ctx, path); |
@@ -160,27 +157,28 @@ impl Ty { | |||
160 | } | 157 | } |
161 | TypeRef::RawPtr(inner, mutability) => { | 158 | TypeRef::RawPtr(inner, mutability) => { |
162 | let inner_ty = Ty::from_hir(ctx, inner); | 159 | let inner_ty = Ty::from_hir(ctx, inner); |
163 | Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) | 160 | Ty::RawPtr(*mutability, Substs::single(inner_ty)) |
164 | } | 161 | } |
165 | TypeRef::Array(inner) => { | 162 | TypeRef::Array(inner) => { |
166 | let inner_ty = Ty::from_hir(ctx, inner); | 163 | let inner_ty = Ty::from_hir(ctx, inner); |
167 | Ty::apply_one(TypeCtor::Array, inner_ty) | 164 | Ty::Array(Substs::single(inner_ty)) |
168 | } | 165 | } |
169 | TypeRef::Slice(inner) => { | 166 | TypeRef::Slice(inner) => { |
170 | let inner_ty = Ty::from_hir(ctx, inner); | 167 | let inner_ty = Ty::from_hir(ctx, inner); |
171 | Ty::apply_one(TypeCtor::Slice, inner_ty) | 168 | Ty::Slice(Substs::single(inner_ty)) |
172 | } | 169 | } |
173 | TypeRef::Reference(inner, _, mutability) => { | 170 | TypeRef::Reference(inner, _, mutability) => { |
174 | let inner_ty = Ty::from_hir(ctx, inner); | 171 | let inner_ty = Ty::from_hir(ctx, inner); |
175 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 172 | Ty::Ref(*mutability, Substs::single(inner_ty)) |
176 | } | 173 | } |
177 | TypeRef::Placeholder => Ty::Unknown, | 174 | TypeRef::Placeholder => Ty::Unknown, |
178 | TypeRef::Fn(params, is_varargs) => { | 175 | TypeRef::Fn(params, is_varargs) => { |
179 | let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); | 176 | let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); |
180 | Ty::apply( | 177 | Ty::Function(FnPointer { |
181 | TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs }, | 178 | num_args: substs.len() - 1, |
182 | sig, | 179 | sig: FnSig { variadic: *is_varargs }, |
183 | ) | 180 | substs, |
181 | }) | ||
184 | } | 182 | } |
185 | TypeRef::DynTrait(bounds) => { | 183 | TypeRef::DynTrait(bounds) => { |
186 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 184 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); |
@@ -414,7 +412,6 @@ impl Ty { | |||
414 | // FIXME: report error | 412 | // FIXME: report error |
415 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), | 413 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), |
416 | }; | 414 | }; |
417 | |||
418 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) | 415 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) |
419 | } | 416 | } |
420 | 417 | ||
@@ -1017,7 +1014,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1017 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); | 1014 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); |
1018 | let generics = generics(db.upcast(), def.into()); | 1015 | let generics = generics(db.upcast(), def.into()); |
1019 | let num_binders = generics.len(); | 1016 | let num_binders = generics.len(); |
1020 | Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) | 1017 | Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) |
1021 | } | 1018 | } |
1022 | 1019 | ||
1023 | /// Build the declared type of a function. This should not need to look at the | 1020 | /// Build the declared type of a function. This should not need to look at the |
@@ -1025,7 +1022,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1025 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { | 1022 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { |
1026 | let generics = generics(db.upcast(), def.into()); | 1023 | let generics = generics(db.upcast(), def.into()); |
1027 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1024 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1028 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1025 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1029 | } | 1026 | } |
1030 | 1027 | ||
1031 | /// Build the declared type of a const. | 1028 | /// Build the declared type of a const. |
@@ -1057,7 +1054,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS | |||
1057 | let params = | 1054 | let params = |
1058 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 1055 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
1059 | let ret = type_for_adt(db, def.into()); | 1056 | let ret = type_for_adt(db, def.into()); |
1060 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) | 1057 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) |
1061 | } | 1058 | } |
1062 | 1059 | ||
1063 | /// Build the type of a tuple struct constructor. | 1060 | /// Build the type of a tuple struct constructor. |
@@ -1068,7 +1065,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T | |||
1068 | } | 1065 | } |
1069 | let generics = generics(db.upcast(), def.into()); | 1066 | let generics = generics(db.upcast(), def.into()); |
1070 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1067 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1071 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1068 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1072 | } | 1069 | } |
1073 | 1070 | ||
1074 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { | 1071 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { |
@@ -1081,7 +1078,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) | |||
1081 | let params = | 1078 | let params = |
1082 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 1079 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
1083 | let ret = type_for_adt(db, def.parent.into()); | 1080 | let ret = type_for_adt(db, def.parent.into()); |
1084 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) | 1081 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) |
1085 | } | 1082 | } |
1086 | 1083 | ||
1087 | /// Build the type of a tuple enum variant constructor. | 1084 | /// Build the type of a tuple enum variant constructor. |
@@ -1093,13 +1090,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) - | |||
1093 | } | 1090 | } |
1094 | let generics = generics(db.upcast(), def.parent.into()); | 1091 | let generics = generics(db.upcast(), def.parent.into()); |
1095 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1092 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1096 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1093 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1097 | } | 1094 | } |
1098 | 1095 | ||
1099 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1096 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { |
1100 | let generics = generics(db.upcast(), adt.into()); | 1097 | let generics = generics(db.upcast(), adt.into()); |
1101 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1098 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1102 | Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) | 1099 | Binders::new(substs.len(), Ty::Adt(adt, substs)) |
1103 | } | 1100 | } |
1104 | 1101 | ||
1105 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | 1102 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { |
@@ -1107,10 +1104,10 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1107 | let resolver = t.resolver(db.upcast()); | 1104 | let resolver = t.resolver(db.upcast()); |
1108 | let ctx = | 1105 | let ctx = |
1109 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1106 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1110 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | ||
1111 | if db.type_alias_data(t).is_extern { | 1107 | if db.type_alias_data(t).is_extern { |
1112 | Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) | 1108 | Binders::new(0, Ty::ForeignType(t)) |
1113 | } else { | 1109 | } else { |
1110 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | ||
1114 | let type_ref = &db.type_alias_data(t).type_ref; | 1111 | let type_ref = &db.type_alias_data(t).type_ref; |
1115 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); | 1112 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
1116 | Binders::new(substs.len(), inner) | 1113 | Binders::new(substs.len(), inner) |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 66d8de959..c8a0ad5f1 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -7,8 +7,8 @@ use std::{iter, sync::Arc}; | |||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use hir_def::{ | 9 | use hir_def::{ |
10 | lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId, | 10 | lang_item::LangItemTarget, type_ref::Mutability, AdtId, AssocContainerId, AssocItemId, |
11 | GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, | 11 | FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId, |
12 | }; | 12 | }; |
13 | use hir_expand::name::Name; | 13 | use hir_expand::name::Name; |
14 | use rustc_hash::{FxHashMap, FxHashSet}; | 14 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -18,15 +18,24 @@ use crate::{ | |||
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | primitive::{self, FloatTy, IntTy, UintTy}, | 19 | primitive::{self, FloatTy, IntTy, UintTy}, |
20 | utils::all_super_traits, | 20 | utils::all_super_traits, |
21 | ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, | 21 | Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment, |
22 | TraitRef, Ty, TyKind, TypeCtor, TypeWalk, | 22 | TraitRef, Ty, TyKind, TypeWalk, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | /// This is used as a key for indexing impls. | 25 | /// This is used as a key for indexing impls. |
26 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 26 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
27 | pub enum TyFingerprint { | 27 | pub enum TyFingerprint { |
28 | Apply(TypeCtor), | 28 | Str, |
29 | Slice, | ||
30 | Array, | ||
31 | Never, | ||
32 | RawPtr(Mutability), | ||
33 | Scalar(Scalar), | ||
34 | Adt(AdtId), | ||
29 | Dyn(TraitId), | 35 | Dyn(TraitId), |
36 | Tuple(usize), | ||
37 | ForeignType(TypeAliasId), | ||
38 | FnPtr(usize, FnSig), | ||
30 | } | 39 | } |
31 | 40 | ||
32 | impl TyFingerprint { | 41 | impl TyFingerprint { |
@@ -34,32 +43,42 @@ impl TyFingerprint { | |||
34 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 43 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not |
35 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 44 | /// `impl &S`. Hence, this will return `None` for reference types and such. |
36 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 45 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
37 | match ty { | 46 | let fp = match ty { |
38 | Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), | 47 | &Ty::Str => TyFingerprint::Str, |
39 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_)), | 48 | &Ty::Never => TyFingerprint::Never, |
40 | _ => None, | 49 | &Ty::Slice(..) => TyFingerprint::Slice, |
41 | } | 50 | &Ty::Array(..) => TyFingerprint::Array, |
51 | &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), | ||
52 | &Ty::Adt(adt, _) => TyFingerprint::Adt(adt), | ||
53 | &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | ||
54 | &Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability), | ||
55 | &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | ||
56 | &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), | ||
57 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
58 | _ => return None, | ||
59 | }; | ||
60 | Some(fp) | ||
42 | } | 61 | } |
43 | } | 62 | } |
44 | 63 | ||
45 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 64 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
46 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))), | 65 | TyFingerprint::Scalar(Scalar::Int(IntTy::I8)), |
47 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))), | 66 | TyFingerprint::Scalar(Scalar::Int(IntTy::I16)), |
48 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), | 67 | TyFingerprint::Scalar(Scalar::Int(IntTy::I32)), |
49 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))), | 68 | TyFingerprint::Scalar(Scalar::Int(IntTy::I64)), |
50 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))), | 69 | TyFingerprint::Scalar(Scalar::Int(IntTy::I128)), |
51 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))), | 70 | TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)), |
52 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))), | 71 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)), |
53 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))), | 72 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)), |
54 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))), | 73 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)), |
55 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))), | 74 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)), |
56 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))), | 75 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)), |
57 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))), | 76 | TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)), |
58 | ]; | 77 | ]; |
59 | 78 | ||
60 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ | 79 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ |
61 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))), | 80 | TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)), |
62 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), | 81 | TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)), |
63 | ]; | 82 | ]; |
64 | 83 | ||
65 | /// Trait impls defined or available in some crate. | 84 | /// Trait impls defined or available in some crate. |
@@ -211,32 +230,29 @@ impl Ty { | |||
211 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 230 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
212 | 231 | ||
213 | let lang_item_targets = match self { | 232 | let lang_item_targets = match self { |
214 | Ty::Apply(a_ty) => match a_ty.ctor { | 233 | Ty::Adt(def_id, _) => { |
215 | TypeCtor::Adt(def_id) => { | 234 | return mod_to_crate_ids(def_id.module(db.upcast())); |
216 | return mod_to_crate_ids(def_id.module(db.upcast())); | 235 | } |
217 | } | 236 | Ty::ForeignType(type_alias_id) => { |
218 | TypeCtor::ForeignType(type_alias_id) => { | 237 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); |
219 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); | 238 | } |
220 | } | 239 | Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
221 | TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 240 | Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), |
222 | TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"), | 241 | Ty::Scalar(Scalar::Float(f)) => match f { |
223 | TypeCtor::Scalar(Scalar::Float(f)) => match f { | 242 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
224 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 243 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
225 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 244 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
226 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | ||
227 | }, | ||
228 | TypeCtor::Scalar(Scalar::Int(t)) => { | ||
229 | lang_item_crate!(primitive::int_ty_to_string(t)) | ||
230 | } | ||
231 | TypeCtor::Scalar(Scalar::Uint(t)) => { | ||
232 | lang_item_crate!(primitive::uint_ty_to_string(t)) | ||
233 | } | ||
234 | TypeCtor::Str => lang_item_crate!("str_alloc", "str"), | ||
235 | TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), | ||
236 | TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), | ||
237 | TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"), | ||
238 | _ => return None, | ||
239 | }, | 245 | }, |
246 | &Ty::Scalar(Scalar::Int(t)) => { | ||
247 | lang_item_crate!(primitive::int_ty_to_string(t)) | ||
248 | } | ||
249 | &Ty::Scalar(Scalar::Uint(t)) => { | ||
250 | lang_item_crate!(primitive::uint_ty_to_string(t)) | ||
251 | } | ||
252 | Ty::Str => lang_item_crate!("str_alloc", "str"), | ||
253 | Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | ||
254 | Ty::RawPtr(Mutability::Shared, _) => lang_item_crate!("const_ptr"), | ||
255 | Ty::RawPtr(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | ||
240 | Ty::Dyn(_) => { | 256 | Ty::Dyn(_) => { |
241 | return self.dyn_trait().and_then(|trait_| { | 257 | return self.dyn_trait().and_then(|trait_| { |
242 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 258 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
@@ -413,7 +429,7 @@ fn iterate_method_candidates_with_autoref( | |||
413 | } | 429 | } |
414 | let refed = Canonical { | 430 | let refed = Canonical { |
415 | kinds: deref_chain[0].kinds.clone(), | 431 | kinds: deref_chain[0].kinds.clone(), |
416 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), | 432 | value: Ty::Ref(Mutability::Shared, Substs::single(deref_chain[0].value.clone())), |
417 | }; | 433 | }; |
418 | if iterate_method_candidates_by_receiver( | 434 | if iterate_method_candidates_by_receiver( |
419 | &refed, | 435 | &refed, |
@@ -429,7 +445,7 @@ fn iterate_method_candidates_with_autoref( | |||
429 | } | 445 | } |
430 | let ref_muted = Canonical { | 446 | let ref_muted = Canonical { |
431 | kinds: deref_chain[0].kinds.clone(), | 447 | kinds: deref_chain[0].kinds.clone(), |
432 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), | 448 | value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), |
433 | }; | 449 | }; |
434 | if iterate_method_candidates_by_receiver( | 450 | if iterate_method_candidates_by_receiver( |
435 | &ref_muted, | 451 | &ref_muted, |
@@ -756,11 +772,9 @@ fn autoderef_method_receiver( | |||
756 | ) -> Vec<Canonical<Ty>> { | 772 | ) -> Vec<Canonical<Ty>> { |
757 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 773 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
758 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 774 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
759 | if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = | 775 | if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) { |
760 | deref_chain.last().map(|ty| &ty.value) | ||
761 | { | ||
762 | let kinds = deref_chain.last().unwrap().kinds.clone(); | 776 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
763 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); | 777 | let unsized_ty = Ty::Slice(parameters.clone()); |
764 | deref_chain.push(Canonical { value: unsized_ty, kinds }) | 778 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
765 | } | 779 | } |
766 | deref_chain | 780 | deref_chain |
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs index a4999c51d..1c01a67ad 100644 --- a/crates/hir_ty/src/op.rs +++ b/crates/hir_ty/src/op.rs | |||
@@ -1,30 +1,23 @@ | |||
1 | //! Helper functions for binary operator type inference. | 1 | //! Helper functions for binary operator type inference. |
2 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; | 2 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; |
3 | 3 | ||
4 | use super::{InferTy, Ty, TypeCtor}; | 4 | use crate::{InferTy, Scalar, Ty}; |
5 | use crate::{ApplicationTy, Scalar}; | ||
6 | 5 | ||
7 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | 6 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { |
8 | match op { | 7 | match op { |
9 | BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), | 8 | BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::Scalar(Scalar::Bool), |
10 | BinaryOp::Assignment { .. } => Ty::unit(), | 9 | BinaryOp::Assignment { .. } => Ty::unit(), |
11 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { | 10 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { |
12 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 11 | Ty::Scalar(Scalar::Int(_)) |
13 | TypeCtor::Scalar(Scalar::Int(_)) | 12 | | Ty::Scalar(Scalar::Uint(_)) |
14 | | TypeCtor::Scalar(Scalar::Uint(_)) | 13 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, |
15 | | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty, | ||
16 | _ => Ty::Unknown, | ||
17 | }, | ||
18 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 14 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, |
19 | _ => Ty::Unknown, | 15 | _ => Ty::Unknown, |
20 | }, | 16 | }, |
21 | BinaryOp::ArithOp(_) => match rhs_ty { | 17 | BinaryOp::ArithOp(_) => match rhs_ty { |
22 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 18 | Ty::Scalar(Scalar::Int(_)) |
23 | TypeCtor::Scalar(Scalar::Int(_)) | 19 | | Ty::Scalar(Scalar::Uint(_)) |
24 | | TypeCtor::Scalar(Scalar::Uint(_)) | 20 | | Ty::Scalar(Scalar::Float(_)) => rhs_ty, |
25 | | TypeCtor::Scalar(Scalar::Float(_)) => rhs_ty, | ||
26 | _ => Ty::Unknown, | ||
27 | }, | ||
28 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, | 21 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, |
29 | _ => Ty::Unknown, | 22 | _ => Ty::Unknown, |
30 | }, | 23 | }, |
@@ -33,13 +26,10 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | |||
33 | 26 | ||
34 | pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | 27 | pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { |
35 | match op { | 28 | match op { |
36 | BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), | 29 | BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool), |
37 | BinaryOp::Assignment { op: None } => lhs_ty, | 30 | BinaryOp::Assignment { op: None } => lhs_ty, |
38 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { | 31 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { |
39 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 32 | Ty::Scalar(_) | Ty::Str => lhs_ty, |
40 | TypeCtor::Scalar(_) | TypeCtor::Str => lhs_ty, | ||
41 | _ => Ty::Unknown, | ||
42 | }, | ||
43 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 33 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, |
44 | _ => Ty::Unknown, | 34 | _ => Ty::Unknown, |
45 | }, | 35 | }, |
@@ -47,12 +37,9 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
47 | BinaryOp::CmpOp(CmpOp::Ord { .. }) | 37 | BinaryOp::CmpOp(CmpOp::Ord { .. }) |
48 | | BinaryOp::Assignment { op: Some(_) } | 38 | | BinaryOp::Assignment { op: Some(_) } |
49 | | BinaryOp::ArithOp(_) => match lhs_ty { | 39 | | BinaryOp::ArithOp(_) => match lhs_ty { |
50 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 40 | Ty::Scalar(Scalar::Int(_)) |
51 | TypeCtor::Scalar(Scalar::Int(_)) | 41 | | Ty::Scalar(Scalar::Uint(_)) |
52 | | TypeCtor::Scalar(Scalar::Uint(_)) | 42 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, |
53 | | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty, | ||
54 | _ => Ty::Unknown, | ||
55 | }, | ||
56 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 43 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, |
57 | _ => Ty::Unknown, | 44 | _ => Ty::Unknown, |
58 | }, | 45 | }, |
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 12ec4657b..2947857a5 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -2491,3 +2491,58 @@ fn inner_use_enum_rename() { | |||
2491 | "#]], | 2491 | "#]], |
2492 | ) | 2492 | ) |
2493 | } | 2493 | } |
2494 | |||
2495 | #[test] | ||
2496 | fn box_into_vec() { | ||
2497 | check_infer( | ||
2498 | r#" | ||
2499 | #[lang = "sized"] | ||
2500 | pub trait Sized {} | ||
2501 | |||
2502 | #[lang = "unsize"] | ||
2503 | pub trait Unsize<T: ?Sized> {} | ||
2504 | |||
2505 | #[lang = "coerce_unsized"] | ||
2506 | pub trait CoerceUnsized<T> {} | ||
2507 | |||
2508 | pub unsafe trait Allocator {} | ||
2509 | |||
2510 | pub struct Global; | ||
2511 | unsafe impl Allocator for Global {} | ||
2512 | |||
2513 | #[lang = "owned_box"] | ||
2514 | #[fundamental] | ||
2515 | pub struct Box<T: ?Sized, A: Allocator = Global>; | ||
2516 | |||
2517 | impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {} | ||
2518 | |||
2519 | pub struct Vec<T, A: Allocator = Global> {} | ||
2520 | |||
2521 | #[lang = "slice"] | ||
2522 | impl<T> [T] {} | ||
2523 | |||
2524 | #[lang = "slice_alloc"] | ||
2525 | impl<T> [T] { | ||
2526 | pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> { | ||
2527 | unimplemented!() | ||
2528 | } | ||
2529 | } | ||
2530 | |||
2531 | fn test() { | ||
2532 | let vec = <[_]>::into_vec(box [1i32]); | ||
2533 | } | ||
2534 | "#, | ||
2535 | expect![[r#" | ||
2536 | 569..573 'self': Box<[T], A> | ||
2537 | 602..634 '{ ... }': Vec<T, A> | ||
2538 | 612..628 'unimpl...ted!()': Vec<T, A> | ||
2539 | 648..694 '{ ...2]); }': () | ||
2540 | 658..661 'vec': Vec<i32, Global> | ||
2541 | 664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global> | ||
2542 | 664..691 '<[_]>:...1i32])': Vec<i32, Global> | ||
2543 | 680..690 'box [1i32]': Box<[i32; _], Global> | ||
2544 | 684..690 '[1i32]': [i32; _] | ||
2545 | 685..689 '1i32': i32 | ||
2546 | "#]], | ||
2547 | ) | ||
2548 | } | ||
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index d74c83737..3f5f5091f 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -19,8 +19,8 @@ use crate::{ | |||
19 | display::HirDisplay, | 19 | display::HirDisplay, |
20 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 20 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
21 | utils::generics, | 21 | utils::generics, |
22 | BoundVar, CallableDefId, DebruijnIndex, FnSig, GenericPredicate, ProjectionPredicate, | 22 | BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate, |
23 | ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 23 | ProjectionTy, Substs, TraitRef, Ty, |
24 | }; | 24 | }; |
25 | use mapping::{ | 25 | use mapping::{ |
26 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, | 26 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, |
@@ -286,9 +286,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
286 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { | 286 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { |
287 | let sig_ty: Ty = | 287 | let sig_ty: Ty = |
288 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); | 288 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); |
289 | let sig = FnSig::from_fn_ptr_substs( | 289 | let sig = CallableSig::from_substs( |
290 | &sig_ty.substs().expect("first closure param should be fn ptr"), | 290 | &sig_ty.substs().expect("first closure param should be fn ptr"), |
291 | false, | ||
292 | ); | 291 | ); |
293 | let io = rust_ir::FnDefInputsAndOutputDatum { | 292 | let io = rust_ir::FnDefInputsAndOutputDatum { |
294 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), | 293 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), |
@@ -489,10 +488,11 @@ pub(crate) fn struct_datum_query( | |||
489 | struct_id: AdtId, | 488 | struct_id: AdtId, |
490 | ) -> Arc<StructDatum> { | 489 | ) -> Arc<StructDatum> { |
491 | debug!("struct_datum {:?}", struct_id); | 490 | debug!("struct_datum {:?}", struct_id); |
492 | let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id)); | 491 | let adt_id = from_chalk(db, struct_id); |
492 | let type_ctor = Ty::Adt(adt_id, Substs::empty()); | ||
493 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | 493 | debug!("struct {:?} = {:?}", struct_id, type_ctor); |
494 | let num_params = type_ctor.num_ty_params(db); | 494 | let num_params = generics(db.upcast(), adt_id.into()).len(); |
495 | let upstream = type_ctor.krate(db) != Some(krate); | 495 | let upstream = adt_id.module(db.upcast()).krate() != krate; |
496 | let where_clauses = type_ctor | 496 | let where_clauses = type_ctor |
497 | .as_generic_def() | 497 | .as_generic_def() |
498 | .map(|generic_def| { | 498 | .map(|generic_def| { |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 5a3cb7906..60d74e21a 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -16,9 +16,8 @@ use crate::{ | |||
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | primitive::UintTy, | 17 | primitive::UintTy, |
18 | traits::{Canonical, Obligation}, | 18 | traits::{Canonical, Obligation}, |
19 | ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, | 19 | CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, |
20 | ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, | 20 | ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, |
21 | TypeCtor, | ||
22 | }; | 21 | }; |
23 | 22 | ||
24 | use super::interner::*; | 23 | use super::interner::*; |
@@ -28,75 +27,67 @@ impl ToChalk for Ty { | |||
28 | type Chalk = chalk_ir::Ty<Interner>; | 27 | type Chalk = chalk_ir::Ty<Interner>; |
29 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { | 28 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { |
30 | match self { | 29 | match self { |
31 | Ty::Apply(apply_ty) => match apply_ty.ctor { | 30 | Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters), |
32 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), | 31 | Ty::Array(parameters) => array_to_chalk(db, parameters), |
33 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), | 32 | Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => { |
34 | TypeCtor::FnPtr { num_args: _, is_varargs } => { | 33 | let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); |
35 | let substitution = | 34 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { |
36 | chalk_ir::FnSubst(apply_ty.parameters.to_chalk(db).shifted_in(&Interner)); | 35 | num_binders: 0, |
37 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | 36 | sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic }, |
38 | num_binders: 0, | 37 | substitution, |
39 | sig: chalk_ir::FnSig { | 38 | }) |
40 | abi: (), | 39 | .intern(&Interner) |
41 | safety: chalk_ir::Safety::Safe, | 40 | } |
42 | variadic: is_varargs, | 41 | Ty::AssociatedType(type_alias, substs) => { |
43 | }, | 42 | let assoc_type = TypeAliasAsAssocType(type_alias); |
44 | substitution, | 43 | let assoc_type_id = assoc_type.to_chalk(db); |
45 | }) | 44 | let substitution = substs.to_chalk(db); |
46 | .intern(&Interner) | 45 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) |
47 | } | 46 | } |
48 | TypeCtor::AssociatedType(type_alias) => { | ||
49 | let assoc_type = TypeAliasAsAssocType(type_alias); | ||
50 | let assoc_type_id = assoc_type.to_chalk(db); | ||
51 | let substitution = apply_ty.parameters.to_chalk(db); | ||
52 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) | ||
53 | } | ||
54 | 47 | ||
55 | TypeCtor::OpaqueType(impl_trait_id) => { | 48 | Ty::OpaqueType(impl_trait_id, substs) => { |
56 | let id = impl_trait_id.to_chalk(db); | 49 | let id = impl_trait_id.to_chalk(db); |
57 | let substitution = apply_ty.parameters.to_chalk(db); | 50 | let substitution = substs.to_chalk(db); |
58 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) | 51 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) |
59 | } | 52 | } |
60 | 53 | ||
61 | TypeCtor::ForeignType(type_alias) => { | 54 | Ty::ForeignType(type_alias) => { |
62 | let foreign_type = TypeAliasAsForeignType(type_alias); | 55 | let foreign_type = TypeAliasAsForeignType(type_alias); |
63 | let foreign_type_id = foreign_type.to_chalk(db); | 56 | let foreign_type_id = foreign_type.to_chalk(db); |
64 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) | 57 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) |
65 | } | 58 | } |
66 | 59 | ||
67 | TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), | 60 | Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), |
68 | 61 | ||
69 | TypeCtor::Tuple { cardinality } => { | 62 | Ty::Tuple(cardinality, substs) => { |
70 | let substitution = apply_ty.parameters.to_chalk(db); | 63 | let substitution = substs.to_chalk(db); |
71 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) | 64 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) |
72 | } | 65 | } |
73 | TypeCtor::RawPtr(mutability) => { | 66 | Ty::RawPtr(mutability, substs) => { |
74 | let ty = apply_ty.parameters[0].clone().to_chalk(db); | 67 | let ty = substs[0].clone().to_chalk(db); |
75 | chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) | 68 | chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) |
76 | } | 69 | } |
77 | TypeCtor::Slice => { | 70 | Ty::Slice(substs) => { |
78 | chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db)) | 71 | chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) |
79 | .intern(&Interner) | 72 | } |
80 | } | 73 | Ty::Str => chalk_ir::TyKind::Str.intern(&Interner), |
81 | TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner), | 74 | Ty::FnDef(callable_def, substs) => { |
82 | TypeCtor::FnDef(callable_def) => { | 75 | let id = callable_def.to_chalk(db); |
83 | let id = callable_def.to_chalk(db); | 76 | let substitution = substs.to_chalk(db); |
84 | let substitution = apply_ty.parameters.to_chalk(db); | 77 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) |
85 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) | 78 | } |
86 | } | 79 | Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), |
87 | TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner), | ||
88 | 80 | ||
89 | TypeCtor::Closure { def, expr } => { | 81 | Ty::Closure(def, expr, substs) => { |
90 | let closure_id = db.intern_closure((def, expr)); | 82 | let closure_id = db.intern_closure((def, expr)); |
91 | let substitution = apply_ty.parameters.to_chalk(db); | 83 | let substitution = substs.to_chalk(db); |
92 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) | 84 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) |
93 | } | 85 | } |
94 | 86 | ||
95 | TypeCtor::Adt(adt_id) => { | 87 | Ty::Adt(adt_id, substs) => { |
96 | let substitution = apply_ty.parameters.to_chalk(db); | 88 | let substitution = substs.to_chalk(db); |
97 | chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) | 89 | chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) |
98 | } | 90 | } |
99 | }, | ||
100 | Ty::Projection(proj_ty) => { | 91 | Ty::Projection(proj_ty) => { |
101 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); | 92 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); |
102 | let substitution = proj_ty.parameters.to_chalk(db); | 93 | let substitution = proj_ty.parameters.to_chalk(db); |
@@ -143,9 +134,7 @@ impl ToChalk for Ty { | |||
143 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { | 134 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { |
144 | match chalk.data(&Interner).kind.clone() { | 135 | match chalk.data(&Interner).kind.clone() { |
145 | chalk_ir::TyKind::Error => Ty::Unknown, | 136 | chalk_ir::TyKind::Error => Ty::Unknown, |
146 | chalk_ir::TyKind::Array(ty, _size) => { | 137 | chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))), |
147 | Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty))) | ||
148 | } | ||
149 | chalk_ir::TyKind::Placeholder(idx) => { | 138 | chalk_ir::TyKind::Placeholder(idx) => { |
150 | assert_eq!(idx.ui, UniverseIndex::ROOT); | 139 | assert_eq!(idx.ui, UniverseIndex::ROOT); |
151 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( | 140 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( |
@@ -171,16 +160,14 @@ impl ToChalk for Ty { | |||
171 | .. | 160 | .. |
172 | }) => { | 161 | }) => { |
173 | assert_eq!(num_binders, 0); | 162 | assert_eq!(num_binders, 0); |
174 | let parameters: Substs = from_chalk( | 163 | let substs: Substs = from_chalk( |
175 | db, | 164 | db, |
176 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), | 165 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), |
177 | ); | 166 | ); |
178 | Ty::Apply(ApplicationTy { | 167 | Ty::Function(FnPointer { |
179 | ctor: TypeCtor::FnPtr { | 168 | num_args: (substs.len() - 1), |
180 | num_args: (parameters.len() - 1) as u16, | 169 | sig: FnSig { variadic }, |
181 | is_varargs: variadic, | 170 | substs, |
182 | }, | ||
183 | parameters, | ||
184 | }) | 171 | }) |
185 | } | 172 | } |
186 | chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), | 173 | chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), |
@@ -196,60 +183,49 @@ impl ToChalk for Ty { | |||
196 | Ty::Dyn(predicates) | 183 | Ty::Dyn(predicates) |
197 | } | 184 | } |
198 | 185 | ||
199 | chalk_ir::TyKind::Adt(struct_id, subst) => { | 186 | chalk_ir::TyKind::Adt(struct_id, subst) => Ty::Adt(struct_id.0, from_chalk(db, subst)), |
200 | apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst) | 187 | chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType( |
201 | } | 188 | from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0, |
202 | chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk( | 189 | from_chalk(db, subst), |
203 | db, | ||
204 | TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0), | ||
205 | subst, | ||
206 | ), | 190 | ), |
191 | |||
207 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { | 192 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { |
208 | apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) | 193 | Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst)) |
209 | } | 194 | } |
210 | 195 | ||
211 | chalk_ir::TyKind::Scalar(scalar) => Ty::simple(TypeCtor::Scalar(scalar)), | 196 | chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar), |
212 | chalk_ir::TyKind::Tuple(cardinality, subst) => { | 197 | chalk_ir::TyKind::Tuple(cardinality, subst) => { |
213 | apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) | 198 | Ty::Tuple(cardinality, from_chalk(db, subst)) |
214 | } | 199 | } |
215 | chalk_ir::TyKind::Raw(mutability, ty) => { | 200 | chalk_ir::TyKind::Raw(mutability, ty) => { |
216 | Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty)) | 201 | Ty::RawPtr(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) |
217 | } | 202 | } |
218 | chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)), | 203 | chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), |
219 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { | 204 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { |
220 | Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty)) | 205 | Ty::Ref(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) |
221 | } | 206 | } |
222 | chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str), | 207 | chalk_ir::TyKind::Str => Ty::Str, |
223 | chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never), | 208 | chalk_ir::TyKind::Never => Ty::Never, |
224 | 209 | ||
225 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { | 210 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { |
226 | let callable_def = from_chalk(db, fn_def_id); | 211 | Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst)) |
227 | apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst) | ||
228 | } | 212 | } |
229 | 213 | ||
230 | chalk_ir::TyKind::Closure(id, subst) => { | 214 | chalk_ir::TyKind::Closure(id, subst) => { |
231 | let id: crate::db::ClosureId = id.into(); | 215 | let id: crate::db::ClosureId = id.into(); |
232 | let (def, expr) = db.lookup_intern_closure(id); | 216 | let (def, expr) = db.lookup_intern_closure(id); |
233 | apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst) | 217 | Ty::Closure(def, expr, from_chalk(db, subst)) |
234 | } | 218 | } |
235 | 219 | ||
236 | chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType( | 220 | chalk_ir::TyKind::Foreign(foreign_def_id) => { |
237 | from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, | 221 | Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0) |
238 | )), | 222 | } |
239 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME | 223 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME |
240 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME | 224 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME |
241 | } | 225 | } |
242 | } | 226 | } |
243 | } | 227 | } |
244 | 228 | ||
245 | fn apply_ty_from_chalk( | ||
246 | db: &dyn HirDatabase, | ||
247 | ctor: TypeCtor, | ||
248 | subst: chalk_ir::Substitution<Interner>, | ||
249 | ) -> Ty { | ||
250 | Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) }) | ||
251 | } | ||
252 | |||
253 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a | 229 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a |
254 | /// fake lifetime here, because Chalks built-in logic may expect it to be there. | 230 | /// fake lifetime here, because Chalks built-in logic may expect it to be there. |
255 | fn ref_to_chalk( | 231 | fn ref_to_chalk( |