diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-02-28 19:16:51 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-02-28 19:16:51 +0000 |
commit | 2fc137b70f9d455676cc99a1a5c7e6e10c3e7cc2 (patch) | |
tree | b9bc6434404e99a0829d01b08285d37f6faa3d2d /crates/hir_ty | |
parent | 0a913fd11194faff9c0100bc78f2d4fe682075aa (diff) | |
parent | faf2dd49e4845e1437b704a28bb5603be5fd605b (diff) |
Merge #7813
7813: Inline TypeCtor into Ty r=flodiebold a=Veykril
This removes the `ApplicationTy` variant from `Ty` bringing the representation a lot closer to chalk's `TyKind`.
Co-authored-by: Lukas Wirth <[email protected]>
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 | 175 | ||||
-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 | 238 | ||||
-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 | 490 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 33 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 126 | ||||
-rw-r--r-- | crates/hir_ty/src/op.rs | 39 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 189 |
15 files changed, 648 insertions, 837 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..cd9dcf6c0 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, FnSig, GenericPredicate, Lifetime, |
7 | GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, | 7 | 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::FnPtr { is_varargs, substs, .. } => { |
325 | let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); | 345 | let sig = FnSig::from_fn_ptr_substs(&substs, *is_varargs); |
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,59 @@ 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, parameters) => { |
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 { | 477 | if parameters.len() > 0 { |
460 | write!(f, "<")?; | 478 | write!(f, "<")?; |
461 | f.write_joined(&*self.parameters.0, ", ")?; | 479 | f.write_joined(&*parameters.0, ", ")?; |
462 | write!(f, ">")?; | 480 | write!(f, ">")?; |
463 | } | 481 | } |
464 | } | 482 | } |
465 | TypeCtor::OpaqueType(opaque_ty_id) => { | 483 | Ty::OpaqueType(opaque_ty_id, parameters) => { |
466 | match opaque_ty_id { | 484 | match opaque_ty_id { |
467 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 485 | &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
468 | let datas = | 486 | let datas = |
469 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 487 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
470 | let data = (*datas) | 488 | let data = (*datas) |
471 | .as_ref() | 489 | .as_ref() |
472 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 490 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
473 | let bounds = data.subst(&self.parameters); | 491 | let bounds = data.subst(¶meters); |
474 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 492 | 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 | 493 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
476 | } | 494 | } |
477 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 495 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { |
478 | write!(f, "impl Future<Output = ")?; | 496 | write!(f, "impl Future<Output = ")?; |
479 | self.parameters[0].hir_fmt(f)?; | 497 | parameters[0].hir_fmt(f)?; |
480 | write!(f, ">")?; | 498 | write!(f, ">")?; |
481 | } | 499 | } |
482 | } | 500 | } |
483 | } | 501 | } |
484 | TypeCtor::Closure { .. } => { | 502 | Ty::Closure { substs, .. } => { |
485 | let sig = self.parameters[0].callable_sig(f.db); | 503 | let sig = substs[0].callable_sig(f.db); |
486 | if let Some(sig) = sig { | 504 | if let Some(sig) = sig { |
487 | if sig.params().is_empty() { | 505 | if sig.params().is_empty() { |
488 | write!(f, "||")?; | 506 | write!(f, "||")?; |
@@ -505,43 +523,6 @@ impl HirDisplay for ApplicationTy { | |||
505 | write!(f, "{{closure}}")?; | 523 | write!(f, "{{closure}}")?; |
506 | } | 524 | } |
507 | } | 525 | } |
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)?, | 526 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, |
546 | Ty::Placeholder(id) => { | 527 | Ty::Placeholder(id) => { |
547 | let generics = generics(f.db.upcast(), id.parent); | 528 | let generics = generics(f.db.upcast(), id.parent); |
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..cd5fb3252 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::FnPtr { .. }) => match from_ty.callable_sig(self.db) { |
96 | match from_ty.callable_sig(self.db) { | 93 | None => return false, |
97 | None => return false, | 94 | Some(sig) => { |
98 | Some(sig) => { | 95 | from_ty = Ty::fn_ptr(sig); |
99 | from_ty = Ty::fn_ptr(sig); | ||
100 | } | ||
101 | } | 96 | } |
102 | } | 97 | }, |
103 | 98 | ||
104 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | 99 | (Ty::Closure { substs, .. }, Ty::FnPtr { .. }) => { |
105 | from_ty = params[0].clone(); | 100 | from_ty = substs[0].clone(); |
106 | } | 101 | } |
107 | 102 | ||
108 | _ => {} | 103 | _ => {} |
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> { | |||
115 | // Auto Deref if cannot coerce | 110 | // Auto Deref if cannot coerce |
116 | match (&from_ty, to_ty) { | 111 | match (&from_ty, to_ty) { |
117 | // FIXME: DerefMut | 112 | // FIXME: DerefMut |
118 | (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { | 113 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), |
119 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
120 | } | ||
121 | 114 | ||
122 | // Otherwise, normal unify | 115 | // Otherwise, normal unify |
123 | _ => self.unify(&from_ty, to_ty), | 116 | _ => self.unify(&from_ty, to_ty), |
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> { | |||
178 | }, | 171 | }, |
179 | ) { | 172 | ) { |
180 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); | 173 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); |
181 | match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { | 174 | let from_ty = self.resolve_ty_shallow(&derefed_ty); |
182 | // Stop when constructor matches. | 175 | // Stop when constructor matches. |
183 | (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { | 176 | if from_ty.equals_ctor(&to_ty) { |
184 | // It will not recurse to `coerce`. | 177 | // It will not recurse to `coerce`. |
185 | return self.table.unify_substs(st1, st2, 0); | 178 | return match (from_ty.substs(), to_ty.substs()) { |
186 | } | 179 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), |
187 | _ => { | 180 | (None, None) => true, |
188 | if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 181 | _ => false, |
189 | return true; | 182 | }; |
190 | } | 183 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
191 | } | 184 | return true; |
192 | } | 185 | } |
193 | } | 186 | } |
194 | 187 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 3fec0e431..2369c9bef 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -18,8 +18,8 @@ use crate::{ | |||
18 | primitive::{self, UintTy}, | 18 | primitive::{self, UintTy}, |
19 | traits::{FnTrait, InEnvironment}, | 19 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 20 | utils::{generics, variant_data, Generics}, |
21 | ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, | 21 | Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, Substs, |
22 | Scalar, Substs, TraitRef, Ty, TypeCtor, | 22 | TraitRef, Ty, |
23 | }; | 23 | }; |
24 | 24 | ||
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 { cardinality: num_args as u16, substs: parameters }; |
86 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, | ||
87 | parameters, | ||
88 | }); | ||
89 | let substs = | 86 | let substs = |
90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 87 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
91 | 88 | ||
@@ -120,10 +117,7 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::Missing => Ty::Unknown, | 117 | Expr::Missing => Ty::Unknown, |
121 | Expr::If { condition, then_branch, else_branch } => { | 118 | Expr::If { condition, then_branch, else_branch } => { |
122 | // if let is desugared to match, so this is always simple if | 119 | // if let is desugared to match, so this is always simple if |
123 | self.infer_expr( | 120 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
124 | *condition, | ||
125 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | ||
126 | ); | ||
127 | 121 | ||
128 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 122 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
129 | let mut both_arms_diverge = Diverges::Always; | 123 | let mut both_arms_diverge = Diverges::Always; |
@@ -178,7 +172,7 @@ impl<'a> InferenceContext<'a> { | |||
178 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 172 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
179 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 173 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
180 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 174 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
181 | Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) | 175 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) |
182 | } | 176 | } |
183 | Expr::Loop { body, label } => { | 177 | Expr::Loop { body, label } => { |
184 | self.breakables.push(BreakableContext { | 178 | self.breakables.push(BreakableContext { |
@@ -196,7 +190,7 @@ impl<'a> InferenceContext<'a> { | |||
196 | if ctxt.may_break { | 190 | if ctxt.may_break { |
197 | ctxt.break_ty | 191 | ctxt.break_ty |
198 | } else { | 192 | } else { |
199 | Ty::simple(TypeCtor::Never) | 193 | Ty::Never |
200 | } | 194 | } |
201 | } | 195 | } |
202 | Expr::While { condition, body, label } => { | 196 | Expr::While { condition, body, label } => { |
@@ -206,10 +200,7 @@ impl<'a> InferenceContext<'a> { | |||
206 | label: label.map(|label| self.body[label].name.clone()), | 200 | label: label.map(|label| self.body[label].name.clone()), |
207 | }); | 201 | }); |
208 | // while let is desugared to a match loop, so this is always simple while | 202 | // while let is desugared to a match loop, so this is always simple while |
209 | self.infer_expr( | 203 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
210 | *condition, | ||
211 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | ||
212 | ); | ||
213 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 204 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
214 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 205 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
215 | // the body may not run, so it diverging doesn't mean we diverge | 206 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -256,12 +247,13 @@ impl<'a> InferenceContext<'a> { | |||
256 | None => self.table.new_type_var(), | 247 | None => self.table.new_type_var(), |
257 | }; | 248 | }; |
258 | sig_tys.push(ret_ty.clone()); | 249 | sig_tys.push(ret_ty.clone()); |
259 | let sig_ty = Ty::apply( | 250 | let sig_ty = Ty::FnPtr { |
260 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 251 | num_args: sig_tys.len() as u16 - 1, |
261 | Substs(sig_tys.clone().into()), | 252 | is_varargs: false, |
262 | ); | 253 | substs: Substs(sig_tys.clone().into()), |
254 | }; | ||
263 | let closure_ty = | 255 | let closure_ty = |
264 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); | 256 | Ty::Closure { def: self.owner, expr: tgt_expr, substs: Substs::single(sig_ty) }; |
265 | 257 | ||
266 | // Eagerly try to relate the closure type with the expected | 258 | // Eagerly try to relate the closure type with the expected |
267 | // type, otherwise we often won't have enough information to | 259 | // type, otherwise we often won't have enough information to |
@@ -312,11 +304,8 @@ impl<'a> InferenceContext<'a> { | |||
312 | Expr::Match { expr, arms } => { | 304 | Expr::Match { expr, arms } => { |
313 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 305 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
314 | 306 | ||
315 | let mut result_ty = if arms.is_empty() { | 307 | let mut result_ty = |
316 | Ty::simple(TypeCtor::Never) | 308 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
317 | } else { | ||
318 | self.table.new_type_var() | ||
319 | }; | ||
320 | 309 | ||
321 | let matchee_diverges = self.diverges; | 310 | let matchee_diverges = self.diverges; |
322 | let mut all_arms_diverge = Diverges::Always; | 311 | let mut all_arms_diverge = Diverges::Always; |
@@ -327,7 +316,7 @@ impl<'a> InferenceContext<'a> { | |||
327 | if let Some(guard_expr) = arm.guard { | 316 | if let Some(guard_expr) = arm.guard { |
328 | self.infer_expr( | 317 | self.infer_expr( |
329 | guard_expr, | 318 | guard_expr, |
330 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), | 319 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
331 | ); | 320 | ); |
332 | } | 321 | } |
333 | 322 | ||
@@ -345,7 +334,7 @@ impl<'a> InferenceContext<'a> { | |||
345 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 334 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
346 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 335 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
347 | } | 336 | } |
348 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 337 | Expr::Continue { .. } => Ty::Never, |
349 | Expr::Break { expr, label } => { | 338 | Expr::Break { expr, label } => { |
350 | let val_ty = if let Some(expr) = expr { | 339 | let val_ty = if let Some(expr) = expr { |
351 | self.infer_expr(*expr, &Expectation::none()) | 340 | self.infer_expr(*expr, &Expectation::none()) |
@@ -370,8 +359,7 @@ impl<'a> InferenceContext<'a> { | |||
370 | expr: tgt_expr, | 359 | expr: tgt_expr, |
371 | }); | 360 | }); |
372 | } | 361 | } |
373 | 362 | Ty::Never | |
374 | Ty::simple(TypeCtor::Never) | ||
375 | } | 363 | } |
376 | Expr::Return { expr } => { | 364 | Expr::Return { expr } => { |
377 | if let Some(expr) = expr { | 365 | if let Some(expr) = expr { |
@@ -380,14 +368,14 @@ impl<'a> InferenceContext<'a> { | |||
380 | let unit = Ty::unit(); | 368 | let unit = Ty::unit(); |
381 | self.coerce(&unit, &self.return_ty.clone()); | 369 | self.coerce(&unit, &self.return_ty.clone()); |
382 | } | 370 | } |
383 | Ty::simple(TypeCtor::Never) | 371 | Ty::Never |
384 | } | 372 | } |
385 | Expr::Yield { expr } => { | 373 | Expr::Yield { expr } => { |
386 | // FIXME: track yield type for coercion | 374 | // FIXME: track yield type for coercion |
387 | if let Some(expr) = expr { | 375 | if let Some(expr) = expr { |
388 | self.infer_expr(*expr, &Expectation::none()); | 376 | self.infer_expr(*expr, &Expectation::none()); |
389 | } | 377 | } |
390 | Ty::simple(TypeCtor::Never) | 378 | Ty::Never |
391 | } | 379 | } |
392 | Expr::RecordLit { path, fields, spread } => { | 380 | Expr::RecordLit { path, fields, spread } => { |
393 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 381 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -397,7 +385,7 @@ impl<'a> InferenceContext<'a> { | |||
397 | 385 | ||
398 | self.unify(&ty, &expected.ty); | 386 | self.unify(&ty, &expected.ty); |
399 | 387 | ||
400 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 388 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
401 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 389 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
402 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 390 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
403 | for (field_idx, field) in fields.iter().enumerate() { | 391 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -436,30 +424,23 @@ impl<'a> InferenceContext<'a> { | |||
436 | }, | 424 | }, |
437 | ) | 425 | ) |
438 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 426 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
439 | Ty::Apply(a_ty) => match a_ty.ctor { | 427 | Ty::Tuple { substs, .. } => { |
440 | TypeCtor::Tuple { .. } => name | 428 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
441 | .as_tuple_index() | 429 | } |
442 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 430 | Ty::Adt(AdtId::StructId(s), parameters) => { |
443 | TypeCtor::Adt(AdtId::StructId(s)) => { | 431 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
444 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 432 | let field = FieldId { parent: s.into(), local_id }; |
445 | let field = FieldId { parent: s.into(), local_id }; | 433 | self.write_field_resolution(tgt_expr, field); |
446 | self.write_field_resolution(tgt_expr, field); | 434 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
447 | self.db.field_types(s.into())[field.local_id] | 435 | }) |
448 | .clone() | 436 | } |
449 | .subst(&a_ty.parameters) | 437 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
450 | }) | 438 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
451 | } | 439 | let field = FieldId { parent: u.into(), local_id }; |
452 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 440 | self.write_field_resolution(tgt_expr, field); |
453 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 441 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) |
454 | let field = FieldId { parent: u.into(), local_id }; | 442 | }) |
455 | self.write_field_resolution(tgt_expr, field); | 443 | } |
456 | self.db.field_types(u.into())[field.local_id] | ||
457 | .clone() | ||
458 | .subst(&a_ty.parameters) | ||
459 | }) | ||
460 | } | ||
461 | _ => None, | ||
462 | }, | ||
463 | _ => None, | 444 | _ => None, |
464 | }) | 445 | }) |
465 | .unwrap_or(Ty::Unknown); | 446 | .unwrap_or(Ty::Unknown); |
@@ -497,19 +478,18 @@ impl<'a> InferenceContext<'a> { | |||
497 | Expectation::none() | 478 | Expectation::none() |
498 | }; | 479 | }; |
499 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 480 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
500 | let ty = match rawness { | 481 | match rawness { |
501 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 482 | Rawness::RawPtr => Ty::RawPtr(*mutability, Substs::single(inner_ty)), |
502 | Rawness::Ref => TypeCtor::Ref(*mutability), | 483 | Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)), |
503 | }; | 484 | } |
504 | Ty::apply_one(ty, inner_ty) | ||
505 | } | 485 | } |
506 | Expr::Box { expr } => { | 486 | Expr::Box { expr } => { |
507 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 487 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
508 | if let Some(box_) = self.resolve_boxed_box() { | 488 | if let Some(box_) = self.resolve_boxed_box() { |
509 | let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); | 489 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
510 | sb = sb.push(inner_ty); | 490 | sb = sb.push(inner_ty); |
511 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 491 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
512 | Ty::apply(TypeCtor::Adt(box_), sb.build()) | 492 | Ty::Adt(box_, sb.build()) |
513 | } else { | 493 | } else { |
514 | Ty::Unknown | 494 | Ty::Unknown |
515 | } | 495 | } |
@@ -539,14 +519,9 @@ impl<'a> InferenceContext<'a> { | |||
539 | UnaryOp::Neg => { | 519 | UnaryOp::Neg => { |
540 | match &inner_ty { | 520 | match &inner_ty { |
541 | // Fast path for builtins | 521 | // Fast path for builtins |
542 | Ty::Apply(ApplicationTy { | 522 | Ty::Scalar(Scalar::Int(_)) |
543 | ctor: TypeCtor::Scalar(Scalar::Int(_)), | 523 | | Ty::Scalar(Scalar::Uint(_)) |
544 | .. | 524 | | Ty::Scalar(Scalar::Float(_)) |
545 | }) | ||
546 | | Ty::Apply(ApplicationTy { | ||
547 | ctor: TypeCtor::Scalar(Scalar::Float(_)), | ||
548 | .. | ||
549 | }) | ||
550 | | Ty::Infer(InferTy::IntVar(..)) | 525 | | Ty::Infer(InferTy::IntVar(..)) |
551 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | 526 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, |
552 | // Otherwise we resolve via the std::ops::Neg trait | 527 | // Otherwise we resolve via the std::ops::Neg trait |
@@ -557,18 +532,9 @@ impl<'a> InferenceContext<'a> { | |||
557 | UnaryOp::Not => { | 532 | UnaryOp::Not => { |
558 | match &inner_ty { | 533 | match &inner_ty { |
559 | // Fast path for builtins | 534 | // Fast path for builtins |
560 | Ty::Apply(ApplicationTy { | 535 | Ty::Scalar(Scalar::Bool) |
561 | ctor: TypeCtor::Scalar(Scalar::Bool), | 536 | | Ty::Scalar(Scalar::Int(_)) |
562 | .. | 537 | | Ty::Scalar(Scalar::Uint(_)) |
563 | }) | ||
564 | | Ty::Apply(ApplicationTy { | ||
565 | ctor: TypeCtor::Scalar(Scalar::Int(_)), | ||
566 | .. | ||
567 | }) | ||
568 | | Ty::Apply(ApplicationTy { | ||
569 | ctor: TypeCtor::Scalar(Scalar::Uint(_)), | ||
570 | .. | ||
571 | }) | ||
572 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 538 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
573 | // Otherwise we resolve via the std::ops::Not trait | 539 | // Otherwise we resolve via the std::ops::Not trait |
574 | _ => self | 540 | _ => self |
@@ -580,9 +546,7 @@ impl<'a> InferenceContext<'a> { | |||
580 | Expr::BinaryOp { lhs, rhs, op } => match op { | 546 | Expr::BinaryOp { lhs, rhs, op } => match op { |
581 | Some(op) => { | 547 | Some(op) => { |
582 | let lhs_expectation = match op { | 548 | let lhs_expectation = match op { |
583 | BinaryOp::LogicOp(..) => { | 549 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
584 | Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))) | ||
585 | } | ||
586 | _ => Expectation::none(), | 550 | _ => Expectation::none(), |
587 | }; | 551 | }; |
588 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 552 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -613,31 +577,31 @@ impl<'a> InferenceContext<'a> { | |||
613 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 577 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
614 | match (range_type, lhs_ty, rhs_ty) { | 578 | match (range_type, lhs_ty, rhs_ty) { |
615 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 579 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
616 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 580 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
617 | None => Ty::Unknown, | 581 | None => Ty::Unknown, |
618 | }, | 582 | }, |
619 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 583 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
620 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 584 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
621 | None => Ty::Unknown, | 585 | None => Ty::Unknown, |
622 | }, | 586 | }, |
623 | (RangeOp::Inclusive, None, Some(ty)) => { | 587 | (RangeOp::Inclusive, None, Some(ty)) => { |
624 | match self.resolve_range_to_inclusive() { | 588 | match self.resolve_range_to_inclusive() { |
625 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 589 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
626 | None => Ty::Unknown, | 590 | None => Ty::Unknown, |
627 | } | 591 | } |
628 | } | 592 | } |
629 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 593 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
630 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 594 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
631 | None => Ty::Unknown, | 595 | None => Ty::Unknown, |
632 | }, | 596 | }, |
633 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 597 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
634 | match self.resolve_range_inclusive() { | 598 | match self.resolve_range_inclusive() { |
635 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 599 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
636 | None => Ty::Unknown, | 600 | None => Ty::Unknown, |
637 | } | 601 | } |
638 | } | 602 | } |
639 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 603 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
640 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 604 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
641 | None => Ty::Unknown, | 605 | None => Ty::Unknown, |
642 | }, | 606 | }, |
643 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 607 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -671,7 +635,7 @@ impl<'a> InferenceContext<'a> { | |||
671 | } | 635 | } |
672 | Expr::Tuple { exprs } => { | 636 | Expr::Tuple { exprs } => { |
673 | let mut tys = match &expected.ty { | 637 | let mut tys = match &expected.ty { |
674 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 638 | Ty::Tuple { substs, .. } => substs |
675 | .iter() | 639 | .iter() |
676 | .cloned() | 640 | .cloned() |
677 | .chain(repeat_with(|| self.table.new_type_var())) | 641 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -684,15 +648,11 @@ impl<'a> InferenceContext<'a> { | |||
684 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 648 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
685 | } | 649 | } |
686 | 650 | ||
687 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 651 | Ty::Tuple { cardinality: tys.len() as u16, substs: Substs(tys.into()) } |
688 | } | 652 | } |
689 | Expr::Array(array) => { | 653 | Expr::Array(array) => { |
690 | let elem_ty = match &expected.ty { | 654 | let elem_ty = match &expected.ty { |
691 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 655 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), |
692 | #[allow(unreachable_patterns)] | ||
693 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | ||
694 | st.as_single().clone() | ||
695 | } | ||
696 | _ => self.table.new_type_var(), | 656 | _ => self.table.new_type_var(), |
697 | }; | 657 | }; |
698 | 658 | ||
@@ -709,42 +669,38 @@ impl<'a> InferenceContext<'a> { | |||
709 | ); | 669 | ); |
710 | self.infer_expr( | 670 | self.infer_expr( |
711 | *repeat, | 671 | *repeat, |
712 | &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( | 672 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
713 | UintTy::Usize, | ||
714 | )))), | ||
715 | ); | 673 | ); |
716 | } | 674 | } |
717 | } | 675 | } |
718 | 676 | ||
719 | Ty::apply_one(TypeCtor::Array, elem_ty) | 677 | Ty::Array(Substs::single(elem_ty)) |
720 | } | 678 | } |
721 | Expr::Literal(lit) => match lit { | 679 | Expr::Literal(lit) => match lit { |
722 | Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), | 680 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
723 | Literal::String(..) => { | 681 | Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)), |
724 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
725 | } | ||
726 | Literal::ByteString(..) => { | 682 | Literal::ByteString(..) => { |
727 | let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); | 683 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
728 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 684 | let array_type = Ty::Array(Substs::single(byte_type)); |
729 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 685 | Ty::Ref(Mutability::Shared, Substs::single(array_type)) |
730 | } | 686 | } |
731 | Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), | 687 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
732 | Literal::Int(_v, ty) => match ty { | 688 | Literal::Int(_v, ty) => match ty { |
733 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int( | 689 | Some(int_ty) => { |
734 | primitive::int_ty_from_builtin(*int_ty), | 690 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
735 | ))), | 691 | } |
736 | None => self.table.new_integer_var(), | 692 | None => self.table.new_integer_var(), |
737 | }, | 693 | }, |
738 | Literal::Uint(_v, ty) => match ty { | 694 | Literal::Uint(_v, ty) => match ty { |
739 | Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint( | 695 | Some(int_ty) => { |
740 | primitive::uint_ty_from_builtin(*int_ty), | 696 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
741 | ))), | 697 | } |
742 | None => self.table.new_integer_var(), | 698 | None => self.table.new_integer_var(), |
743 | }, | 699 | }, |
744 | Literal::Float(_v, ty) => match ty { | 700 | Literal::Float(_v, ty) => match ty { |
745 | Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float( | 701 | Some(float_ty) => { |
746 | primitive::float_ty_from_builtin(*float_ty), | 702 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
747 | ))), | 703 | } |
748 | None => self.table.new_float_var(), | 704 | None => self.table.new_float_var(), |
749 | }, | 705 | }, |
750 | }, | 706 | }, |
@@ -857,7 +813,7 @@ impl<'a> InferenceContext<'a> { | |||
857 | // Apply autoref so the below unification works correctly | 813 | // Apply autoref so the below unification works correctly |
858 | // FIXME: return correct autorefs from lookup_method | 814 | // FIXME: return correct autorefs from lookup_method |
859 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 815 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
860 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 816 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
861 | _ => derefed_receiver_ty, | 817 | _ => derefed_receiver_ty, |
862 | }; | 818 | }; |
863 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 819 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -934,30 +890,26 @@ impl<'a> InferenceContext<'a> { | |||
934 | } | 890 | } |
935 | 891 | ||
936 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 892 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
937 | if let Ty::Apply(a_ty) = callable_ty { | 893 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
938 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 894 | let generic_predicates = self.db.generic_predicates(def.into()); |
939 | let generic_predicates = self.db.generic_predicates(def.into()); | 895 | for predicate in generic_predicates.iter() { |
940 | for predicate in generic_predicates.iter() { | 896 | let predicate = predicate.clone().subst(parameters); |
941 | let predicate = predicate.clone().subst(&a_ty.parameters); | 897 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
942 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 898 | self.obligations.push(obligation); |
943 | self.obligations.push(obligation); | ||
944 | } | ||
945 | } | 899 | } |
946 | // add obligation for trait implementation, if this is a trait method | 900 | } |
947 | match def { | 901 | // add obligation for trait implementation, if this is a trait method |
948 | CallableDefId::FunctionId(f) => { | 902 | match def { |
949 | if let AssocContainerId::TraitId(trait_) = | 903 | CallableDefId::FunctionId(f) => { |
950 | f.lookup(self.db.upcast()).container | 904 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
951 | { | 905 | { |
952 | // construct a TraitDef | 906 | // construct a TraitDef |
953 | let substs = a_ty | 907 | let substs = |
954 | .parameters | 908 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
955 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 909 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
956 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
957 | } | ||
958 | } | 910 | } |
959 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
960 | } | 911 | } |
912 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
961 | } | 913 | } |
962 | } | 914 | } |
963 | } | 915 | } |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index d974f805b..e96e08c3c 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -13,7 +13,7 @@ use hir_expand::name::Name; | |||
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 { cardinality: inner_tys.len() as u16, substs: Substs(inner_tys.into()) } |
142 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | ||
143 | Substs(inner_tys.into()), | ||
144 | ) | ||
145 | } | 142 | } |
146 | Pat::Or(ref pats) => { | 143 | Pat::Or(ref pats) => { |
147 | if let Some((first_pat, rest)) = pats.split_first() { | 144 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> { | |||
165 | _ => &Ty::Unknown, | 162 | _ => &Ty::Unknown, |
166 | }; | 163 | }; |
167 | let subty = self.infer_pat(*pat, expectation, default_bm); | 164 | let subty = self.infer_pat(*pat, expectation, default_bm); |
168 | Ty::apply_one(TypeCtor::Ref(*mutability), subty) | 165 | Ty::Ref(*mutability, Substs::single(subty)) |
169 | } | 166 | } |
170 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 167 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
171 | p.as_ref(), | 168 | p.as_ref(), |
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> { | |||
198 | 195 | ||
199 | let bound_ty = match mode { | 196 | let bound_ty = match mode { |
200 | BindingMode::Ref(mutability) => { | 197 | BindingMode::Ref(mutability) => { |
201 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) | 198 | Ty::Ref(mutability, Substs::single(inner_ty.clone())) |
202 | } | 199 | } |
203 | BindingMode::Move => inner_ty.clone(), | 200 | BindingMode::Move => inner_ty.clone(), |
204 | }; | 201 | }; |
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> { | |||
207 | return inner_ty; | 204 | return inner_ty; |
208 | } | 205 | } |
209 | Pat::Slice { prefix, slice, suffix } => { | 206 | Pat::Slice { prefix, slice, suffix } => { |
210 | let (container_ty, elem_ty) = match &expected { | 207 | let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { |
211 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), | 208 | Ty::Array(st) => (Ty::Array, st.as_single().clone()), |
212 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), | 209 | Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), |
213 | _ => (TypeCtor::Slice, Ty::Unknown), | 210 | _ => (Ty::Slice, Ty::Unknown), |
214 | }; | 211 | }; |
215 | 212 | ||
216 | for pat_id in prefix.iter().chain(suffix) { | 213 | for pat_id in prefix.iter().chain(suffix) { |
217 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 214 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
218 | } | 215 | } |
219 | 216 | ||
220 | let pat_ty = Ty::apply_one(container_ty, elem_ty); | 217 | let pat_ty = container_ty(Substs::single(elem_ty)); |
221 | if let Some(slice_pat_id) = slice { | 218 | if let Some(slice_pat_id) = slice { |
222 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 219 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
223 | } | 220 | } |
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> { | |||
239 | }; | 236 | }; |
240 | 237 | ||
241 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 238 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); |
242 | Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) | 239 | Ty::Adt(box_adt, Substs::single(inner_ty)) |
243 | } | 240 | } |
244 | None => Ty::Unknown, | 241 | None => Ty::Unknown, |
245 | }, | 242 | }, |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 57eb8cede..2852ad5bf 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -9,7 +9,7 @@ use test_utils::mark; | |||
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..117d69f01 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, |
@@ -293,10 +107,80 @@ impl TypeWalk for ProjectionTy { | |||
293 | /// This should be cheap to clone. | 107 | /// This should be cheap to clone. |
294 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 108 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
295 | pub enum Ty { | 109 | pub enum Ty { |
296 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | 110 | /// Structures, enumerations and unions. |
297 | /// type like `bool`, a struct, tuple, function pointer, reference or | 111 | Adt(AdtId, Substs), |
298 | /// several other things. | 112 | |
299 | Apply(ApplicationTy), | 113 | /// Represents an associated item like `Iterator::Item`. This is used |
114 | /// when we have tried to normalize a projection like `T::Item` but | ||
115 | /// couldn't find a better representation. In that case, we generate | ||
116 | /// an **application type** like `(Iterator::Item)<T>`. | ||
117 | AssociatedType(TypeAliasId, Substs), | ||
118 | |||
119 | /// a scalar type like `bool` or `u32` | ||
120 | Scalar(Scalar), | ||
121 | |||
122 | /// A tuple type. For example, `(i32, bool)`. | ||
123 | Tuple { cardinality: u16, substs: Substs }, | ||
124 | |||
125 | /// An array with the given length. Written as `[T; n]`. | ||
126 | Array(Substs), | ||
127 | |||
128 | /// The pointee of an array slice. Written as `[T]`. | ||
129 | Slice(Substs), | ||
130 | |||
131 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
132 | RawPtr(Mutability, Substs), | ||
133 | |||
134 | /// A reference; a pointer with an associated lifetime. Written as | ||
135 | /// `&'a mut T` or `&'a T`. | ||
136 | Ref(Mutability, Substs), | ||
137 | |||
138 | /// This represents a placeholder for an opaque type in situations where we | ||
139 | /// don't know the hidden type (i.e. currently almost always). This is | ||
140 | /// analogous to the `AssociatedType` type constructor. | ||
141 | /// It is also used as the type of async block, with one type parameter | ||
142 | /// representing the Future::Output type. | ||
143 | OpaqueType(OpaqueTyId, Substs), | ||
144 | |||
145 | /// The anonymous type of a function declaration/definition. Each | ||
146 | /// function has a unique type, which is output (for a function | ||
147 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
148 | /// | ||
149 | /// This includes tuple struct / enum variant constructors as well. | ||
150 | /// | ||
151 | /// For example the type of `bar` here: | ||
152 | /// | ||
153 | /// ``` | ||
154 | /// fn foo() -> i32 { 1 } | ||
155 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
156 | /// ``` | ||
157 | FnDef(CallableDefId, Substs), | ||
158 | |||
159 | /// The pointee of a string slice. Written as `str`. | ||
160 | Str, | ||
161 | |||
162 | /// The never type `!`. | ||
163 | Never, | ||
164 | |||
165 | /// The type of a specific closure. | ||
166 | /// | ||
167 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
168 | /// parameter. | ||
169 | Closure { def: DefWithBodyId, expr: ExprId, substs: Substs }, | ||
170 | |||
171 | /// Represents a foreign type declared in external blocks. | ||
172 | ForeignType(TypeAliasId, Substs), | ||
173 | |||
174 | /// A pointer to a function. Written as `fn() -> i32`. | ||
175 | /// | ||
176 | /// For example the type of `bar` here: | ||
177 | /// | ||
178 | /// ``` | ||
179 | /// fn foo() -> i32 { 1 } | ||
180 | /// let bar: fn() -> i32 = foo; | ||
181 | /// ``` | ||
182 | // FIXME make this a Ty variant like in Chalk | ||
183 | FnPtr { num_args: u16, is_varargs: bool, substs: Substs }, | ||
300 | 184 | ||
301 | /// A "projection" type corresponds to an (unnormalized) | 185 | /// A "projection" type corresponds to an (unnormalized) |
302 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 186 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
@@ -420,10 +304,6 @@ impl Substs { | |||
420 | Substs::builder(generic_params.len()) | 304 | Substs::builder(generic_params.len()) |
421 | } | 305 | } |
422 | 306 | ||
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 { | 307 | fn builder(param_count: usize) -> SubstsBuilder { |
428 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | 308 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } |
429 | } | 309 | } |
@@ -701,54 +581,42 @@ impl TypeWalk for FnSig { | |||
701 | } | 581 | } |
702 | 582 | ||
703 | impl Ty { | 583 | 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 { | 584 | pub fn unit() -> Self { |
714 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 585 | Ty::Tuple { cardinality: 0, substs: Substs::empty() } |
715 | } | 586 | } |
587 | |||
716 | pub fn fn_ptr(sig: FnSig) -> Self { | 588 | pub fn fn_ptr(sig: FnSig) -> Self { |
717 | Ty::apply( | 589 | Ty::FnPtr { |
718 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, | 590 | num_args: sig.params().len() as u16, |
719 | Substs(sig.params_and_return), | 591 | is_varargs: sig.is_varargs, |
720 | ) | 592 | substs: Substs(sig.params_and_return), |
593 | } | ||
721 | } | 594 | } |
595 | |||
722 | pub fn builtin(builtin: BuiltinType) -> Self { | 596 | pub fn builtin(builtin: BuiltinType) -> Self { |
723 | Ty::simple(match builtin { | 597 | match builtin { |
724 | BuiltinType::Char => TypeCtor::Scalar(Scalar::Char), | 598 | BuiltinType::Char => Ty::Scalar(Scalar::Char), |
725 | BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool), | 599 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), |
726 | BuiltinType::Str => TypeCtor::Str, | 600 | BuiltinType::Str => Ty::Str, |
727 | BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), | 601 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), |
728 | BuiltinType::Uint(t) => { | 602 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), |
729 | TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))) | 603 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), |
730 | } | 604 | } |
731 | BuiltinType::Float(t) => { | ||
732 | TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))) | ||
733 | } | ||
734 | }) | ||
735 | } | 605 | } |
736 | 606 | ||
737 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 607 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
738 | match self { | 608 | match self { |
739 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 609 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), |
740 | Some((parameters.as_single(), *mutability)) | ||
741 | } | ||
742 | _ => None, | 610 | _ => None, |
743 | } | 611 | } |
744 | } | 612 | } |
745 | 613 | ||
746 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 614 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
747 | match self { | 615 | match self { |
748 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 616 | Ty::Ref(mutability, parameters) => { |
749 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 617 | Some((parameters.as_single(), Rawness::Ref, *mutability)) |
750 | } | 618 | } |
751 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | 619 | Ty::RawPtr(mutability, parameters) => { |
752 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | 620 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) |
753 | } | 621 | } |
754 | _ => None, | 622 | _ => None, |
@@ -758,7 +626,7 @@ impl Ty { | |||
758 | pub fn strip_references(&self) -> &Ty { | 626 | pub fn strip_references(&self) -> &Ty { |
759 | let mut t: &Ty = self; | 627 | let mut t: &Ty = self; |
760 | 628 | ||
761 | while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { | 629 | while let Ty::Ref(_mutability, parameters) = t { |
762 | t = parameters.as_single(); | 630 | t = parameters.as_single(); |
763 | } | 631 | } |
764 | 632 | ||
@@ -767,30 +635,64 @@ impl Ty { | |||
767 | 635 | ||
768 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { | 636 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { |
769 | match self { | 637 | match self { |
770 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 638 | Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)), |
771 | Some((*adt_def, parameters)) | ||
772 | } | ||
773 | _ => None, | 639 | _ => None, |
774 | } | 640 | } |
775 | } | 641 | } |
776 | 642 | ||
777 | pub fn as_tuple(&self) -> Option<&Substs> { | 643 | pub fn as_tuple(&self) -> Option<&Substs> { |
778 | match self { | 644 | match self { |
779 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | 645 | Ty::Tuple { substs: parameters, .. } => Some(parameters), |
780 | Some(parameters) | 646 | _ => None, |
781 | } | 647 | } |
648 | } | ||
649 | |||
650 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | ||
651 | match *self { | ||
652 | Ty::Adt(adt, ..) => Some(adt.into()), | ||
653 | Ty::FnDef(callable, ..) => Some(callable.into()), | ||
654 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | ||
655 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | ||
782 | _ => None, | 656 | _ => None, |
783 | } | 657 | } |
784 | } | 658 | } |
785 | 659 | ||
786 | pub fn is_never(&self) -> bool { | 660 | pub fn is_never(&self) -> bool { |
787 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 661 | matches!(self, Ty::Never) |
788 | } | 662 | } |
789 | 663 | ||
790 | pub fn is_unknown(&self) -> bool { | 664 | pub fn is_unknown(&self) -> bool { |
791 | matches!(self, Ty::Unknown) | 665 | matches!(self, Ty::Unknown) |
792 | } | 666 | } |
793 | 667 | ||
668 | pub fn equals_ctor(&self, other: &Ty) -> bool { | ||
669 | match (self, other) { | ||
670 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | ||
671 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | ||
672 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | ||
673 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | ||
674 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | ||
675 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | ||
676 | (Ty::Closure { def, expr, .. }, Ty::Closure { def: def2, expr: expr2, .. }) => { | ||
677 | expr == expr2 && def == def2 | ||
678 | } | ||
679 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
680 | | (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => { | ||
681 | mutability == mutability2 | ||
682 | } | ||
683 | ( | ||
684 | Ty::FnPtr { num_args, is_varargs, .. }, | ||
685 | Ty::FnPtr { num_args: num_args2, is_varargs: is_varargs2, .. }, | ||
686 | ) => num_args == num_args2 && is_varargs == is_varargs2, | ||
687 | (Ty::Tuple { cardinality, .. }, Ty::Tuple { cardinality: cardinality2, .. }) => { | ||
688 | cardinality == cardinality2 | ||
689 | } | ||
690 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | ||
691 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | ||
692 | _ => false, | ||
693 | } | ||
694 | } | ||
695 | |||
794 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 696 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
795 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 697 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
796 | match self { | 698 | match self { |
@@ -809,41 +711,32 @@ impl Ty { | |||
809 | 711 | ||
810 | fn builtin_deref(&self) -> Option<Ty> { | 712 | fn builtin_deref(&self) -> Option<Ty> { |
811 | match self { | 713 | match self { |
812 | Ty::Apply(a_ty) => match a_ty.ctor { | 714 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), |
813 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 715 | 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, | 716 | _ => None, |
818 | } | 717 | } |
819 | } | 718 | } |
820 | 719 | ||
821 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 720 | pub fn as_fn_def(&self) -> Option<FunctionId> { |
822 | match self { | 721 | match self { |
823 | &Ty::Apply(ApplicationTy { | 722 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), |
824 | ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), | ||
825 | .. | ||
826 | }) => Some(func), | ||
827 | _ => None, | 723 | _ => None, |
828 | } | 724 | } |
829 | } | 725 | } |
830 | 726 | ||
831 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 727 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { |
832 | match self { | 728 | match self { |
833 | Ty::Apply(a_ty) => match a_ty.ctor { | 729 | Ty::FnPtr { is_varargs, substs: parameters, .. } => { |
834 | TypeCtor::FnPtr { is_varargs, .. } => { | 730 | Some(FnSig::from_fn_ptr_substs(¶meters, *is_varargs)) |
835 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | 731 | } |
836 | } | 732 | Ty::FnDef(def, parameters) => { |
837 | TypeCtor::FnDef(def) => { | 733 | let sig = db.callable_item_signature(*def); |
838 | let sig = db.callable_item_signature(def); | 734 | Some(sig.subst(¶meters)) |
839 | Some(sig.subst(&a_ty.parameters)) | 735 | } |
840 | } | 736 | Ty::Closure { substs: parameters, .. } => { |
841 | TypeCtor::Closure { .. } => { | 737 | let sig_param = ¶meters[0]; |
842 | let sig_param = &a_ty.parameters[0]; | 738 | sig_param.callable_sig(db) |
843 | sig_param.callable_sig(db) | 739 | } |
844 | } | ||
845 | _ => None, | ||
846 | }, | ||
847 | _ => None, | 740 | _ => None, |
848 | } | 741 | } |
849 | } | 742 | } |
@@ -852,28 +745,69 @@ impl Ty { | |||
852 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | 745 | /// 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 | 746 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
854 | /// `Option<u32>` afterwards.) | 747 | /// `Option<u32>` afterwards.) |
855 | pub fn apply_substs(self, substs: Substs) -> Ty { | 748 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
856 | match self { | 749 | match &mut self { |
857 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | 750 | Ty::Adt(_, substs) |
858 | assert_eq!(previous_substs.len(), substs.len()); | 751 | | Ty::Slice(substs) |
859 | Ty::Apply(ApplicationTy { ctor, parameters: substs }) | 752 | | Ty::Array(substs) |
753 | | Ty::RawPtr(_, substs) | ||
754 | | Ty::Ref(_, substs) | ||
755 | | Ty::FnDef(_, substs) | ||
756 | | Ty::FnPtr { substs, .. } | ||
757 | | Ty::Tuple { substs, .. } | ||
758 | | Ty::OpaqueType(_, substs) | ||
759 | | Ty::AssociatedType(_, substs) | ||
760 | | Ty::ForeignType(_, substs) | ||
761 | | Ty::Closure { substs, .. } => { | ||
762 | assert_eq!(substs.len(), new_substs.len()); | ||
763 | *substs = new_substs; | ||
860 | } | 764 | } |
861 | _ => self, | 765 | _ => (), |
862 | } | 766 | } |
767 | self | ||
863 | } | 768 | } |
864 | 769 | ||
865 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 770 | /// 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`. | 771 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
867 | pub fn substs(&self) -> Option<Substs> { | 772 | pub fn substs(&self) -> Option<&Substs> { |
773 | match self { | ||
774 | Ty::Adt(_, substs) | ||
775 | | Ty::Slice(substs) | ||
776 | | Ty::Array(substs) | ||
777 | | Ty::RawPtr(_, substs) | ||
778 | | Ty::Ref(_, substs) | ||
779 | | Ty::FnDef(_, substs) | ||
780 | | Ty::FnPtr { substs, .. } | ||
781 | | Ty::Tuple { substs, .. } | ||
782 | | Ty::OpaqueType(_, substs) | ||
783 | | Ty::AssociatedType(_, substs) | ||
784 | | Ty::ForeignType(_, substs) | ||
785 | | Ty::Closure { substs, .. } => Some(substs), | ||
786 | _ => None, | ||
787 | } | ||
788 | } | ||
789 | |||
790 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | ||
868 | match self { | 791 | match self { |
869 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | 792 | Ty::Adt(_, substs) |
793 | | Ty::Slice(substs) | ||
794 | | Ty::Array(substs) | ||
795 | | Ty::RawPtr(_, substs) | ||
796 | | Ty::Ref(_, substs) | ||
797 | | Ty::FnDef(_, substs) | ||
798 | | Ty::FnPtr { substs, .. } | ||
799 | | Ty::Tuple { substs, .. } | ||
800 | | Ty::OpaqueType(_, substs) | ||
801 | | Ty::AssociatedType(_, substs) | ||
802 | | Ty::ForeignType(_, substs) | ||
803 | | Ty::Closure { substs, .. } => Some(substs), | ||
870 | _ => None, | 804 | _ => None, |
871 | } | 805 | } |
872 | } | 806 | } |
873 | 807 | ||
874 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 808 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
875 | match self { | 809 | match self { |
876 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | 810 | Ty::OpaqueType(opaque_ty_id, ..) => { |
877 | match opaque_ty_id { | 811 | match opaque_ty_id { |
878 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 812 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { |
879 | let krate = def.module(db.upcast()).krate(); | 813 | let krate = def.module(db.upcast()).krate(); |
@@ -934,7 +868,7 @@ impl Ty { | |||
934 | 868 | ||
935 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 869 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
936 | match self { | 870 | match self { |
937 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | 871 | Ty::AssociatedType(type_alias_id, ..) => { |
938 | match type_alias_id.lookup(db.upcast()).container { | 872 | match type_alias_id.lookup(db.upcast()).container { |
939 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 873 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
940 | _ => None, | 874 | _ => None, |
@@ -1049,11 +983,6 @@ pub trait TypeWalk { | |||
1049 | impl TypeWalk for Ty { | 983 | impl TypeWalk for Ty { |
1050 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 984 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
1051 | match self { | 985 | 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) => { | 986 | Ty::Projection(p_ty) => { |
1058 | for t in p_ty.parameters.iter() { | 987 | for t in p_ty.parameters.iter() { |
1059 | t.walk(f); | 988 | t.walk(f); |
@@ -1069,7 +998,13 @@ impl TypeWalk for Ty { | |||
1069 | t.walk(f); | 998 | t.walk(f); |
1070 | } | 999 | } |
1071 | } | 1000 | } |
1072 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1001 | _ => { |
1002 | if let Some(substs) = self.substs() { | ||
1003 | for t in substs.iter() { | ||
1004 | t.walk(f); | ||
1005 | } | ||
1006 | } | ||
1007 | } | ||
1073 | } | 1008 | } |
1074 | f(self); | 1009 | f(self); |
1075 | } | 1010 | } |
@@ -1080,9 +1015,6 @@ impl TypeWalk for Ty { | |||
1080 | binders: DebruijnIndex, | 1015 | binders: DebruijnIndex, |
1081 | ) { | 1016 | ) { |
1082 | match self { | 1017 | match self { |
1083 | Ty::Apply(a_ty) => { | ||
1084 | a_ty.parameters.walk_mut_binders(f, binders); | ||
1085 | } | ||
1086 | Ty::Projection(p_ty) => { | 1018 | Ty::Projection(p_ty) => { |
1087 | p_ty.parameters.walk_mut_binders(f, binders); | 1019 | p_ty.parameters.walk_mut_binders(f, binders); |
1088 | } | 1020 | } |
@@ -1094,7 +1026,11 @@ impl TypeWalk for Ty { | |||
1094 | Ty::Opaque(o_ty) => { | 1026 | Ty::Opaque(o_ty) => { |
1095 | o_ty.parameters.walk_mut_binders(f, binders); | 1027 | o_ty.parameters.walk_mut_binders(f, binders); |
1096 | } | 1028 | } |
1097 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1029 | _ => { |
1030 | if let Some(substs) = self.substs_mut() { | ||
1031 | substs.walk_mut_binders(f, binders); | ||
1032 | } | ||
1033 | } | ||
1098 | } | 1034 | } |
1099 | f(self, binders); | 1035 | f(self, binders); |
1100 | } | 1036 | } |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 99b0ecf3b..6b919a09e 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -33,7 +33,7 @@ use crate::{ | |||
33 | }, | 33 | }, |
34 | Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, | 34 | Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, |
35 | ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, | 35 | ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, |
36 | TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 36 | 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 { cardinality: inner_tys.len() as u16, substs: 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,24 @@ 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 sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); |
180 | Ty::apply( | 177 | Ty::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs, substs: sig } |
181 | TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs }, | ||
182 | sig, | ||
183 | ) | ||
184 | } | 178 | } |
185 | TypeRef::DynTrait(bounds) => { | 179 | TypeRef::DynTrait(bounds) => { |
186 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 180 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); |
@@ -414,7 +408,6 @@ impl Ty { | |||
414 | // FIXME: report error | 408 | // FIXME: report error |
415 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), | 409 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), |
416 | }; | 410 | }; |
417 | |||
418 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) | 411 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) |
419 | } | 412 | } |
420 | 413 | ||
@@ -1025,7 +1018,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1025 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { | 1018 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { |
1026 | let generics = generics(db.upcast(), def.into()); | 1019 | let generics = generics(db.upcast(), def.into()); |
1027 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1020 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1028 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1021 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1029 | } | 1022 | } |
1030 | 1023 | ||
1031 | /// Build the declared type of a const. | 1024 | /// Build the declared type of a const. |
@@ -1068,7 +1061,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T | |||
1068 | } | 1061 | } |
1069 | let generics = generics(db.upcast(), def.into()); | 1062 | let generics = generics(db.upcast(), def.into()); |
1070 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1063 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1071 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1064 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1072 | } | 1065 | } |
1073 | 1066 | ||
1074 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { | 1067 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { |
@@ -1093,13 +1086,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) - | |||
1093 | } | 1086 | } |
1094 | let generics = generics(db.upcast(), def.parent.into()); | 1087 | let generics = generics(db.upcast(), def.parent.into()); |
1095 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1088 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1096 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1089 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1097 | } | 1090 | } |
1098 | 1091 | ||
1099 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1092 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { |
1100 | let generics = generics(db.upcast(), adt.into()); | 1093 | let generics = generics(db.upcast(), adt.into()); |
1101 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1094 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1102 | Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) | 1095 | Binders::new(substs.len(), Ty::Adt(adt, substs)) |
1103 | } | 1096 | } |
1104 | 1097 | ||
1105 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | 1098 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { |
@@ -1109,7 +1102,7 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1109 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1102 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1110 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1103 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1111 | if db.type_alias_data(t).is_extern { | 1104 | if db.type_alias_data(t).is_extern { |
1112 | Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) | 1105 | Binders::new(substs.len(), Ty::ForeignType(t, substs)) |
1113 | } else { | 1106 | } else { |
1114 | let type_ref = &db.type_alias_data(t).type_ref; | 1107 | 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)); | 1108 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 66d8de959..087b67935 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, InEnvironment, Scalar, Substs, TraitEnvironment, TraitRef, Ty, |
22 | TraitRef, Ty, TyKind, TypeCtor, TypeWalk, | 22 | 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 { cardinality: u16 }, | ||
37 | ForeignType(TypeAliasId), | ||
38 | FnPtr { num_args: u16, is_varargs: bool }, | ||
30 | } | 39 | } |
31 | 40 | ||
32 | impl TyFingerprint { | 41 | impl TyFingerprint { |
@@ -34,32 +43,44 @@ 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: u16, .. } => TyFingerprint::Tuple { cardinality: u16 }, | ||
54 | &Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability), | ||
55 | &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | ||
56 | &Ty::FnPtr { num_args, is_varargs, .. } => { | ||
57 | TyFingerprint::FnPtr { num_args, is_varargs } | ||
58 | } | ||
59 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
60 | _ => return None, | ||
61 | }; | ||
62 | Some(fp) | ||
42 | } | 63 | } |
43 | } | 64 | } |
44 | 65 | ||
45 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 66 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
46 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))), | 67 | TyFingerprint::Scalar(Scalar::Int(IntTy::I8)), |
47 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))), | 68 | TyFingerprint::Scalar(Scalar::Int(IntTy::I16)), |
48 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), | 69 | TyFingerprint::Scalar(Scalar::Int(IntTy::I32)), |
49 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))), | 70 | TyFingerprint::Scalar(Scalar::Int(IntTy::I64)), |
50 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))), | 71 | TyFingerprint::Scalar(Scalar::Int(IntTy::I128)), |
51 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))), | 72 | TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)), |
52 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))), | 73 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)), |
53 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))), | 74 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)), |
54 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))), | 75 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)), |
55 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))), | 76 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)), |
56 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))), | 77 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)), |
57 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))), | 78 | TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)), |
58 | ]; | 79 | ]; |
59 | 80 | ||
60 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ | 81 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ |
61 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))), | 82 | TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)), |
62 | TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), | 83 | TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)), |
63 | ]; | 84 | ]; |
64 | 85 | ||
65 | /// Trait impls defined or available in some crate. | 86 | /// Trait impls defined or available in some crate. |
@@ -211,32 +232,29 @@ impl Ty { | |||
211 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 232 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
212 | 233 | ||
213 | let lang_item_targets = match self { | 234 | let lang_item_targets = match self { |
214 | Ty::Apply(a_ty) => match a_ty.ctor { | 235 | Ty::Adt(def_id, _) => { |
215 | TypeCtor::Adt(def_id) => { | 236 | return mod_to_crate_ids(def_id.module(db.upcast())); |
216 | return mod_to_crate_ids(def_id.module(db.upcast())); | 237 | } |
217 | } | 238 | Ty::ForeignType(type_alias_id, _) => { |
218 | TypeCtor::ForeignType(type_alias_id) => { | 239 | 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())); | 240 | } |
220 | } | 241 | Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
221 | TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 242 | Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), |
222 | TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"), | 243 | Ty::Scalar(Scalar::Float(f)) => match f { |
223 | TypeCtor::Scalar(Scalar::Float(f)) => match f { | 244 | // 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) | 245 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
225 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 246 | 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 | }, | 247 | }, |
248 | &Ty::Scalar(Scalar::Int(t)) => { | ||
249 | lang_item_crate!(primitive::int_ty_to_string(t)) | ||
250 | } | ||
251 | &Ty::Scalar(Scalar::Uint(t)) => { | ||
252 | lang_item_crate!(primitive::uint_ty_to_string(t)) | ||
253 | } | ||
254 | Ty::Str => lang_item_crate!("str_alloc", "str"), | ||
255 | Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | ||
256 | Ty::RawPtr(Mutability::Shared, _) => lang_item_crate!("const_ptr"), | ||
257 | Ty::RawPtr(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | ||
240 | Ty::Dyn(_) => { | 258 | Ty::Dyn(_) => { |
241 | return self.dyn_trait().and_then(|trait_| { | 259 | return self.dyn_trait().and_then(|trait_| { |
242 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 260 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
@@ -413,7 +431,7 @@ fn iterate_method_candidates_with_autoref( | |||
413 | } | 431 | } |
414 | let refed = Canonical { | 432 | let refed = Canonical { |
415 | kinds: deref_chain[0].kinds.clone(), | 433 | kinds: deref_chain[0].kinds.clone(), |
416 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), | 434 | value: Ty::Ref(Mutability::Shared, Substs::single(deref_chain[0].value.clone())), |
417 | }; | 435 | }; |
418 | if iterate_method_candidates_by_receiver( | 436 | if iterate_method_candidates_by_receiver( |
419 | &refed, | 437 | &refed, |
@@ -429,7 +447,7 @@ fn iterate_method_candidates_with_autoref( | |||
429 | } | 447 | } |
430 | let ref_muted = Canonical { | 448 | let ref_muted = Canonical { |
431 | kinds: deref_chain[0].kinds.clone(), | 449 | kinds: deref_chain[0].kinds.clone(), |
432 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), | 450 | value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), |
433 | }; | 451 | }; |
434 | if iterate_method_candidates_by_receiver( | 452 | if iterate_method_candidates_by_receiver( |
435 | &ref_muted, | 453 | &ref_muted, |
@@ -756,11 +774,9 @@ fn autoderef_method_receiver( | |||
756 | ) -> Vec<Canonical<Ty>> { | 774 | ) -> Vec<Canonical<Ty>> { |
757 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 775 | 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!) | 776 | // 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 })) = | 777 | 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(); | 778 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
763 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); | 779 | let unsized_ty = Ty::Slice(parameters.clone()); |
764 | deref_chain.push(Canonical { value: unsized_ty, kinds }) | 780 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
765 | } | 781 | } |
766 | deref_chain | 782 | 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/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index d74c83737..c53e327da 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -20,7 +20,7 @@ use crate::{ | |||
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, DebruijnIndex, FnSig, 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, |
@@ -489,10 +489,11 @@ pub(crate) fn struct_datum_query( | |||
489 | struct_id: AdtId, | 489 | struct_id: AdtId, |
490 | ) -> Arc<StructDatum> { | 490 | ) -> Arc<StructDatum> { |
491 | debug!("struct_datum {:?}", struct_id); | 491 | debug!("struct_datum {:?}", struct_id); |
492 | let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id)); | 492 | let adt_id = from_chalk(db, struct_id); |
493 | let type_ctor = Ty::Adt(adt_id, Substs::empty()); | ||
493 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | 494 | debug!("struct {:?} = {:?}", struct_id, type_ctor); |
494 | let num_params = type_ctor.num_ty_params(db); | 495 | let num_params = generics(db.upcast(), adt_id.into()).len(); |
495 | let upstream = type_ctor.krate(db) != Some(krate); | 496 | let upstream = adt_id.module(db.upcast()).krate() != krate; |
496 | let where_clauses = type_ctor | 497 | let where_clauses = type_ctor |
497 | .as_generic_def() | 498 | .as_generic_def() |
498 | .map(|generic_def| { | 499 | .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..297ddeabd 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, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, ProjectionPredicate, |
20 | ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, | 20 | ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, |
21 | TypeCtor, | ||
22 | }; | 21 | }; |
23 | 22 | ||
24 | use super::interner::*; | 23 | use super::interner::*; |
@@ -28,75 +27,71 @@ 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::FnPtr { num_args: _, is_varargs, 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 { |
38 | num_binders: 0, | 37 | abi: (), |
39 | sig: chalk_ir::FnSig { | 38 | safety: chalk_ir::Safety::Safe, |
40 | abi: (), | 39 | variadic: is_varargs, |
41 | safety: chalk_ir::Safety::Safe, | 40 | }, |
42 | variadic: is_varargs, | 41 | substitution, |
43 | }, | 42 | }) |
44 | substitution, | 43 | .intern(&Interner) |
45 | }) | 44 | } |
46 | .intern(&Interner) | 45 | Ty::AssociatedType(type_alias, substs) => { |
47 | } | 46 | let assoc_type = TypeAliasAsAssocType(type_alias); |
48 | TypeCtor::AssociatedType(type_alias) => { | 47 | let assoc_type_id = assoc_type.to_chalk(db); |
49 | let assoc_type = TypeAliasAsAssocType(type_alias); | 48 | let substitution = substs.to_chalk(db); |
50 | let assoc_type_id = assoc_type.to_chalk(db); | 49 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) |
51 | let substitution = apply_ty.parameters.to_chalk(db); | 50 | } |
52 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) | ||
53 | } | ||
54 | 51 | ||
55 | TypeCtor::OpaqueType(impl_trait_id) => { | 52 | Ty::OpaqueType(impl_trait_id, substs) => { |
56 | let id = impl_trait_id.to_chalk(db); | 53 | let id = impl_trait_id.to_chalk(db); |
57 | let substitution = apply_ty.parameters.to_chalk(db); | 54 | let substitution = substs.to_chalk(db); |
58 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) | 55 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) |
59 | } | 56 | } |
60 | 57 | ||
61 | TypeCtor::ForeignType(type_alias) => { | 58 | Ty::ForeignType(type_alias, _) => { |
62 | let foreign_type = TypeAliasAsForeignType(type_alias); | 59 | let foreign_type = TypeAliasAsForeignType(type_alias); |
63 | let foreign_type_id = foreign_type.to_chalk(db); | 60 | let foreign_type_id = foreign_type.to_chalk(db); |
64 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) | 61 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) |
65 | } | 62 | } |
66 | 63 | ||
67 | TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), | 64 | Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), |
68 | 65 | ||
69 | TypeCtor::Tuple { cardinality } => { | 66 | Ty::Tuple { cardinality, substs } => { |
70 | let substitution = apply_ty.parameters.to_chalk(db); | 67 | let substitution = substs.to_chalk(db); |
71 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) | 68 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) |
72 | } | 69 | } |
73 | TypeCtor::RawPtr(mutability) => { | 70 | Ty::RawPtr(mutability, substs) => { |
74 | let ty = apply_ty.parameters[0].clone().to_chalk(db); | 71 | let ty = substs[0].clone().to_chalk(db); |
75 | chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) | 72 | chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) |
76 | } | 73 | } |
77 | TypeCtor::Slice => { | 74 | Ty::Slice(substs) => { |
78 | chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db)) | 75 | chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) |
79 | .intern(&Interner) | 76 | } |
80 | } | 77 | Ty::Str => chalk_ir::TyKind::Str.intern(&Interner), |
81 | TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner), | 78 | Ty::FnDef(callable_def, substs) => { |
82 | TypeCtor::FnDef(callable_def) => { | 79 | let id = callable_def.to_chalk(db); |
83 | let id = callable_def.to_chalk(db); | 80 | let substitution = substs.to_chalk(db); |
84 | let substitution = apply_ty.parameters.to_chalk(db); | 81 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) |
85 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) | 82 | } |
86 | } | 83 | Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), |
87 | TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner), | ||
88 | 84 | ||
89 | TypeCtor::Closure { def, expr } => { | 85 | Ty::Closure { def, expr, substs } => { |
90 | let closure_id = db.intern_closure((def, expr)); | 86 | let closure_id = db.intern_closure((def, expr)); |
91 | let substitution = apply_ty.parameters.to_chalk(db); | 87 | let substitution = substs.to_chalk(db); |
92 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) | 88 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) |
93 | } | 89 | } |
94 | 90 | ||
95 | TypeCtor::Adt(adt_id) => { | 91 | Ty::Adt(adt_id, substs) => { |
96 | let substitution = apply_ty.parameters.to_chalk(db); | 92 | let substitution = substs.to_chalk(db); |
97 | chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) | 93 | chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) |
98 | } | 94 | } |
99 | }, | ||
100 | Ty::Projection(proj_ty) => { | 95 | Ty::Projection(proj_ty) => { |
101 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); | 96 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); |
102 | let substitution = proj_ty.parameters.to_chalk(db); | 97 | let substitution = proj_ty.parameters.to_chalk(db); |
@@ -143,9 +138,7 @@ impl ToChalk for Ty { | |||
143 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { | 138 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { |
144 | match chalk.data(&Interner).kind.clone() { | 139 | match chalk.data(&Interner).kind.clone() { |
145 | chalk_ir::TyKind::Error => Ty::Unknown, | 140 | chalk_ir::TyKind::Error => Ty::Unknown, |
146 | chalk_ir::TyKind::Array(ty, _size) => { | 141 | 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) => { | 142 | chalk_ir::TyKind::Placeholder(idx) => { |
150 | assert_eq!(idx.ui, UniverseIndex::ROOT); | 143 | assert_eq!(idx.ui, UniverseIndex::ROOT); |
151 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( | 144 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( |
@@ -175,13 +168,11 @@ impl ToChalk for Ty { | |||
175 | db, | 168 | db, |
176 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), | 169 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), |
177 | ); | 170 | ); |
178 | Ty::Apply(ApplicationTy { | 171 | Ty::FnPtr { |
179 | ctor: TypeCtor::FnPtr { | 172 | num_args: (parameters.len() - 1) as u16, |
180 | num_args: (parameters.len() - 1) as u16, | 173 | is_varargs: variadic, |
181 | is_varargs: variadic, | 174 | substs: parameters, |
182 | }, | 175 | } |
183 | parameters, | ||
184 | }) | ||
185 | } | 176 | } |
186 | chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), | 177 | chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), |
187 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, | 178 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, |
@@ -196,60 +187,50 @@ impl ToChalk for Ty { | |||
196 | Ty::Dyn(predicates) | 187 | Ty::Dyn(predicates) |
197 | } | 188 | } |
198 | 189 | ||
199 | chalk_ir::TyKind::Adt(struct_id, subst) => { | 190 | 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) | 191 | chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType( |
201 | } | 192 | from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0, |
202 | chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk( | 193 | from_chalk(db, subst), |
203 | db, | ||
204 | TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0), | ||
205 | subst, | ||
206 | ), | 194 | ), |
195 | |||
207 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { | 196 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { |
208 | apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) | 197 | Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst)) |
209 | } | 198 | } |
210 | 199 | ||
211 | chalk_ir::TyKind::Scalar(scalar) => Ty::simple(TypeCtor::Scalar(scalar)), | 200 | chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar), |
212 | chalk_ir::TyKind::Tuple(cardinality, subst) => { | 201 | chalk_ir::TyKind::Tuple(cardinality, subst) => { |
213 | apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) | 202 | Ty::Tuple { cardinality: cardinality as u16, substs: from_chalk(db, subst) } |
214 | } | 203 | } |
215 | chalk_ir::TyKind::Raw(mutability, ty) => { | 204 | chalk_ir::TyKind::Raw(mutability, ty) => { |
216 | Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty)) | 205 | Ty::RawPtr(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) |
217 | } | 206 | } |
218 | chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)), | 207 | chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), |
219 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { | 208 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { |
220 | Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty)) | 209 | Ty::Ref(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) |
221 | } | 210 | } |
222 | chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str), | 211 | chalk_ir::TyKind::Str => Ty::Str, |
223 | chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never), | 212 | chalk_ir::TyKind::Never => Ty::Never, |
224 | 213 | ||
225 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { | 214 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { |
226 | let callable_def = from_chalk(db, fn_def_id); | 215 | Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst)) |
227 | apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst) | ||
228 | } | 216 | } |
229 | 217 | ||
230 | chalk_ir::TyKind::Closure(id, subst) => { | 218 | chalk_ir::TyKind::Closure(id, subst) => { |
231 | let id: crate::db::ClosureId = id.into(); | 219 | let id: crate::db::ClosureId = id.into(); |
232 | let (def, expr) = db.lookup_intern_closure(id); | 220 | let (def, expr) = db.lookup_intern_closure(id); |
233 | apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst) | 221 | Ty::Closure { def, expr, substs: from_chalk(db, subst) } |
234 | } | 222 | } |
235 | 223 | ||
236 | chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType( | 224 | chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::ForeignType( |
237 | from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, | 225 | from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, |
238 | )), | 226 | Substs::empty(), |
227 | ), | ||
239 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME | 228 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME |
240 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME | 229 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME |
241 | } | 230 | } |
242 | } | 231 | } |
243 | } | 232 | } |
244 | 233 | ||
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 | 234 | /// 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. | 235 | /// fake lifetime here, because Chalks built-in logic may expect it to be there. |
255 | fn ref_to_chalk( | 236 | fn ref_to_chalk( |