diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 11 | ||||
-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 | 187 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 41 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 85 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 229 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 27 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 200 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 599 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 80 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 166 | ||||
-rw-r--r-- | crates/hir_ty/src/op.rs | 50 | ||||
-rw-r--r-- | crates/hir_ty/src/primitive.rs | 160 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/simple.rs | 55 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 24 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 310 |
19 files changed, 1000 insertions, 1251 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index ece68183e..be1fd1f13 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -81,7 +81,7 @@ fn deref_by_trait( | |||
81 | 81 | ||
82 | // Now do the assoc type projection | 82 | // Now do the assoc type projection |
83 | let projection = super::traits::ProjectionPredicate { | 83 | let projection = super::traits::ProjectionPredicate { |
84 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), | 84 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), |
85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, | 85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, |
86 | }; | 86 | }; |
87 | 87 | ||
@@ -89,8 +89,10 @@ fn deref_by_trait( | |||
89 | 89 | ||
90 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; | 90 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; |
91 | 91 | ||
92 | let canonical = | 92 | let canonical = Canonical::new( |
93 | Canonical::new(in_env, ty.value.kinds.iter().copied().chain(Some(super::TyKind::General))); | 93 | in_env, |
94 | ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), | ||
95 | ); | ||
94 | 96 | ||
95 | let solution = db.trait_solve(krate, canonical)?; | 97 | let solution = db.trait_solve(krate, canonical)?; |
96 | 98 | ||
@@ -112,7 +114,8 @@ fn deref_by_trait( | |||
112 | // new variables in that case | 114 | // new variables in that case |
113 | 115 | ||
114 | for i in 1..vars.0.kinds.len() { | 116 | for i in 1..vars.0.kinds.len() { |
115 | if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | 117 | if vars.0.value[i - 1] |
118 | != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | ||
116 | { | 119 | { |
117 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); | 120 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); |
118 | return None; | 121 | return None; |
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..e77a20fea 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::Raw(..) = &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 271fcbfaf..f3a4333cb 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -3,8 +3,9 @@ | |||
3 | use std::{borrow::Cow, fmt}; | 3 | use std::{borrow::Cow, fmt}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, | 6 | db::HirDatabase, primitive, utils::generics, AliasTy, CallableDefId, CallableSig, |
7 | Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 7 | GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, |
8 | TraitRef, Ty, | ||
8 | }; | 9 | }; |
9 | use arrayvec::ArrayVec; | 10 | use arrayvec::ArrayVec; |
10 | use hir_def::{ | 11 | use hir_def::{ |
@@ -234,36 +235,62 @@ impl HirDisplay for &Ty { | |||
234 | } | 235 | } |
235 | } | 236 | } |
236 | 237 | ||
237 | impl HirDisplay for ApplicationTy { | 238 | impl HirDisplay for ProjectionTy { |
239 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
240 | if f.should_truncate() { | ||
241 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
242 | } | ||
243 | |||
244 | let trait_ = f.db.trait_data(self.trait_(f.db)); | ||
245 | let first_parameter = self.parameters[0].into_displayable( | ||
246 | f.db, | ||
247 | f.max_size, | ||
248 | f.omit_verbose_types, | ||
249 | f.display_target, | ||
250 | ); | ||
251 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | ||
252 | if self.parameters.len() > 1 { | ||
253 | write!(f, "<")?; | ||
254 | f.write_joined(&self.parameters[1..], ", ")?; | ||
255 | write!(f, ">")?; | ||
256 | } | ||
257 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | ||
258 | Ok(()) | ||
259 | } | ||
260 | } | ||
261 | |||
262 | impl HirDisplay for Ty { | ||
238 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 263 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
239 | if f.should_truncate() { | 264 | if f.should_truncate() { |
240 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 265 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
241 | } | 266 | } |
242 | 267 | ||
243 | match self.ctor { | 268 | match self { |
244 | TypeCtor::Bool => write!(f, "bool")?, | 269 | Ty::Never => write!(f, "!")?, |
245 | TypeCtor::Char => write!(f, "char")?, | 270 | Ty::Str => write!(f, "str")?, |
246 | TypeCtor::Int(t) => write!(f, "{}", t)?, | 271 | Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, |
247 | TypeCtor::Float(t) => write!(f, "{}", t)?, | 272 | Ty::Scalar(Scalar::Char) => write!(f, "char")?, |
248 | TypeCtor::Str => write!(f, "str")?, | 273 | &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, |
249 | TypeCtor::Slice => { | 274 | &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, |
250 | let t = self.parameters.as_single(); | 275 | &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, |
276 | Ty::Slice(parameters) => { | ||
277 | let t = parameters.as_single(); | ||
251 | write!(f, "[")?; | 278 | write!(f, "[")?; |
252 | t.hir_fmt(f)?; | 279 | t.hir_fmt(f)?; |
253 | write!(f, "]")?; | 280 | write!(f, "]")?; |
254 | } | 281 | } |
255 | TypeCtor::Array => { | 282 | Ty::Array(parameters) => { |
256 | let t = self.parameters.as_single(); | 283 | let t = parameters.as_single(); |
257 | write!(f, "[")?; | 284 | write!(f, "[")?; |
258 | t.hir_fmt(f)?; | 285 | t.hir_fmt(f)?; |
259 | write!(f, "; _]")?; | 286 | write!(f, "; _]")?; |
260 | } | 287 | } |
261 | TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { | 288 | Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { |
262 | let t = self.parameters.as_single(); | 289 | let t = parameters.as_single(); |
263 | let ty_display = | 290 | let ty_display = |
264 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | 291 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); |
265 | 292 | ||
266 | if matches!(self.ctor, TypeCtor::RawPtr(_)) { | 293 | if matches!(self, Ty::Raw(..)) { |
267 | write!(f, "*{}", m.as_keyword_for_ptr())?; | 294 | write!(f, "*{}", m.as_keyword_for_ptr())?; |
268 | } else { | 295 | } else { |
269 | write!(f, "&{}", m.as_keyword_for_ref())?; | 296 | write!(f, "&{}", m.as_keyword_for_ref())?; |
@@ -274,10 +301,10 @@ impl HirDisplay for ApplicationTy { | |||
274 | Ty::Dyn(predicates) if predicates.len() > 1 => { | 301 | Ty::Dyn(predicates) if predicates.len() > 1 => { |
275 | Cow::Borrowed(predicates.as_ref()) | 302 | Cow::Borrowed(predicates.as_ref()) |
276 | } | 303 | } |
277 | &Ty::Opaque(OpaqueTy { | 304 | &Ty::Alias(AliasTy::Opaque(OpaqueTy { |
278 | opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), | 305 | opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), |
279 | ref parameters, | 306 | ref parameters, |
280 | }) => { | 307 | })) => { |
281 | datas = | 308 | datas = |
282 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 309 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
283 | let data = (*datas) | 310 | let data = (*datas) |
@@ -304,25 +331,24 @@ impl HirDisplay for ApplicationTy { | |||
304 | write!(f, "{}", ty_display)?; | 331 | write!(f, "{}", ty_display)?; |
305 | } | 332 | } |
306 | } | 333 | } |
307 | TypeCtor::Never => write!(f, "!")?, | 334 | Ty::Tuple(_, substs) => { |
308 | TypeCtor::Tuple { .. } => { | 335 | if substs.len() == 1 { |
309 | let ts = &self.parameters; | ||
310 | if ts.len() == 1 { | ||
311 | write!(f, "(")?; | 336 | write!(f, "(")?; |
312 | ts[0].hir_fmt(f)?; | 337 | substs[0].hir_fmt(f)?; |
313 | write!(f, ",)")?; | 338 | write!(f, ",)")?; |
314 | } else { | 339 | } else { |
315 | write!(f, "(")?; | 340 | write!(f, "(")?; |
316 | f.write_joined(&*ts.0, ", ")?; | 341 | f.write_joined(&*substs.0, ", ")?; |
317 | write!(f, ")")?; | 342 | write!(f, ")")?; |
318 | } | 343 | } |
319 | } | 344 | } |
320 | TypeCtor::FnPtr { is_varargs, .. } => { | 345 | Ty::Function(fn_ptr) => { |
321 | let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); | 346 | let sig = CallableSig::from_fn_ptr(fn_ptr); |
322 | sig.hir_fmt(f)?; | 347 | sig.hir_fmt(f)?; |
323 | } | 348 | } |
324 | TypeCtor::FnDef(def) => { | 349 | Ty::FnDef(def, parameters) => { |
325 | let sig = f.db.callable_item_signature(def).subst(&self.parameters); | 350 | let def = *def; |
351 | let sig = f.db.callable_item_signature(def).subst(parameters); | ||
326 | match def { | 352 | match def { |
327 | CallableDefId::FunctionId(ff) => { | 353 | CallableDefId::FunctionId(ff) => { |
328 | write!(f, "fn {}", f.db.function_data(ff).name)? | 354 | write!(f, "fn {}", f.db.function_data(ff).name)? |
@@ -332,7 +358,7 @@ impl HirDisplay for ApplicationTy { | |||
332 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? | 358 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? |
333 | } | 359 | } |
334 | }; | 360 | }; |
335 | if self.parameters.len() > 0 { | 361 | if parameters.len() > 0 { |
336 | let generics = generics(f.db.upcast(), def.into()); | 362 | let generics = generics(f.db.upcast(), def.into()); |
337 | let (parent_params, self_param, type_params, _impl_trait_params) = | 363 | let (parent_params, self_param, type_params, _impl_trait_params) = |
338 | generics.provenance_split(); | 364 | generics.provenance_split(); |
@@ -340,7 +366,7 @@ impl HirDisplay for ApplicationTy { | |||
340 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? | 366 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? |
341 | if total_len > 0 { | 367 | if total_len > 0 { |
342 | write!(f, "<")?; | 368 | write!(f, "<")?; |
343 | f.write_joined(&self.parameters.0[..total_len], ", ")?; | 369 | f.write_joined(¶meters.0[..total_len], ", ")?; |
344 | write!(f, ">")?; | 370 | write!(f, ">")?; |
345 | } | 371 | } |
346 | } | 372 | } |
@@ -359,10 +385,10 @@ impl HirDisplay for ApplicationTy { | |||
359 | write!(f, " -> {}", ret_display)?; | 385 | write!(f, " -> {}", ret_display)?; |
360 | } | 386 | } |
361 | } | 387 | } |
362 | TypeCtor::Adt(def_id) => { | 388 | Ty::Adt(def_id, parameters) => { |
363 | match f.display_target { | 389 | match f.display_target { |
364 | DisplayTarget::Diagnostics | DisplayTarget::Test => { | 390 | DisplayTarget::Diagnostics | DisplayTarget::Test => { |
365 | let name = match def_id { | 391 | let name = match *def_id { |
366 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), | 392 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), |
367 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), | 393 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), |
368 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), | 394 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), |
@@ -372,7 +398,7 @@ impl HirDisplay for ApplicationTy { | |||
372 | DisplayTarget::SourceCode { module_id } => { | 398 | DisplayTarget::SourceCode { module_id } => { |
373 | if let Some(path) = find_path::find_path( | 399 | if let Some(path) = find_path::find_path( |
374 | f.db.upcast(), | 400 | f.db.upcast(), |
375 | ItemInNs::Types(def_id.into()), | 401 | ItemInNs::Types((*def_id).into()), |
376 | module_id, | 402 | module_id, |
377 | ) { | 403 | ) { |
378 | write!(f, "{}", path)?; | 404 | write!(f, "{}", path)?; |
@@ -384,19 +410,18 @@ impl HirDisplay for ApplicationTy { | |||
384 | } | 410 | } |
385 | } | 411 | } |
386 | 412 | ||
387 | if self.parameters.len() > 0 { | 413 | if parameters.len() > 0 { |
388 | let parameters_to_write = | 414 | let parameters_to_write = |
389 | if f.display_target.is_source_code() || f.omit_verbose_types() { | 415 | if f.display_target.is_source_code() || f.omit_verbose_types() { |
390 | match self | 416 | match self |
391 | .ctor | ||
392 | .as_generic_def() | 417 | .as_generic_def() |
393 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 418 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
394 | .filter(|defaults| !defaults.is_empty()) | 419 | .filter(|defaults| !defaults.is_empty()) |
395 | { | 420 | { |
396 | None => self.parameters.0.as_ref(), | 421 | None => parameters.0.as_ref(), |
397 | Some(default_parameters) => { | 422 | Some(default_parameters) => { |
398 | let mut default_from = 0; | 423 | let mut default_from = 0; |
399 | for (i, parameter) in self.parameters.iter().enumerate() { | 424 | for (i, parameter) in parameters.iter().enumerate() { |
400 | match (parameter, default_parameters.get(i)) { | 425 | match (parameter, default_parameters.get(i)) { |
401 | (&Ty::Unknown, _) | (_, None) => { | 426 | (&Ty::Unknown, _) | (_, None) => { |
402 | default_from = i + 1; | 427 | default_from = i + 1; |
@@ -404,18 +429,18 @@ impl HirDisplay for ApplicationTy { | |||
404 | (_, Some(default_parameter)) => { | 429 | (_, Some(default_parameter)) => { |
405 | let actual_default = default_parameter | 430 | let actual_default = default_parameter |
406 | .clone() | 431 | .clone() |
407 | .subst(&self.parameters.prefix(i)); | 432 | .subst(¶meters.prefix(i)); |
408 | if parameter != &actual_default { | 433 | if parameter != &actual_default { |
409 | default_from = i + 1; | 434 | default_from = i + 1; |
410 | } | 435 | } |
411 | } | 436 | } |
412 | } | 437 | } |
413 | } | 438 | } |
414 | &self.parameters.0[0..default_from] | 439 | ¶meters.0[0..default_from] |
415 | } | 440 | } |
416 | } | 441 | } |
417 | } else { | 442 | } else { |
418 | self.parameters.0.as_ref() | 443 | parameters.0.as_ref() |
419 | }; | 444 | }; |
420 | if !parameters_to_write.is_empty() { | 445 | if !parameters_to_write.is_empty() { |
421 | write!(f, "<")?; | 446 | write!(f, "<")?; |
@@ -424,61 +449,54 @@ impl HirDisplay for ApplicationTy { | |||
424 | } | 449 | } |
425 | } | 450 | } |
426 | } | 451 | } |
427 | TypeCtor::AssociatedType(type_alias) => { | 452 | Ty::AssociatedType(type_alias, parameters) => { |
428 | let trait_ = match type_alias.lookup(f.db.upcast()).container { | 453 | let trait_ = match type_alias.lookup(f.db.upcast()).container { |
429 | AssocContainerId::TraitId(it) => it, | 454 | AssocContainerId::TraitId(it) => it, |
430 | _ => panic!("not an associated type"), | 455 | _ => panic!("not an associated type"), |
431 | }; | 456 | }; |
432 | let trait_ = f.db.trait_data(trait_); | 457 | let trait_ = f.db.trait_data(trait_); |
433 | let type_alias_data = f.db.type_alias_data(type_alias); | 458 | let type_alias_data = f.db.type_alias_data(*type_alias); |
434 | 459 | ||
435 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) | 460 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
436 | if f.display_target.is_test() { | 461 | if f.display_target.is_test() { |
437 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; | 462 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; |
438 | if self.parameters.len() > 0 { | 463 | if parameters.len() > 0 { |
439 | write!(f, "<")?; | 464 | write!(f, "<")?; |
440 | f.write_joined(&*self.parameters.0, ", ")?; | 465 | f.write_joined(&*parameters.0, ", ")?; |
441 | write!(f, ">")?; | 466 | write!(f, ">")?; |
442 | } | 467 | } |
443 | } else { | 468 | } else { |
444 | let projection_ty = ProjectionTy { | 469 | let projection_ty = |
445 | associated_ty: type_alias, | 470 | ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; |
446 | parameters: self.parameters.clone(), | ||
447 | }; | ||
448 | 471 | ||
449 | projection_ty.hir_fmt(f)?; | 472 | projection_ty.hir_fmt(f)?; |
450 | } | 473 | } |
451 | } | 474 | } |
452 | TypeCtor::ForeignType(type_alias) => { | 475 | Ty::ForeignType(type_alias) => { |
453 | let type_alias = f.db.type_alias_data(type_alias); | 476 | let type_alias = f.db.type_alias_data(*type_alias); |
454 | write!(f, "{}", type_alias.name)?; | 477 | write!(f, "{}", type_alias.name)?; |
455 | if self.parameters.len() > 0 { | ||
456 | write!(f, "<")?; | ||
457 | f.write_joined(&*self.parameters.0, ", ")?; | ||
458 | write!(f, ">")?; | ||
459 | } | ||
460 | } | 478 | } |
461 | TypeCtor::OpaqueType(opaque_ty_id) => { | 479 | Ty::OpaqueType(opaque_ty_id, parameters) => { |
462 | match opaque_ty_id { | 480 | match opaque_ty_id { |
463 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 481 | &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
464 | let datas = | 482 | let datas = |
465 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 483 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
466 | let data = (*datas) | 484 | let data = (*datas) |
467 | .as_ref() | 485 | .as_ref() |
468 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 486 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
469 | let bounds = data.subst(&self.parameters); | 487 | let bounds = data.subst(¶meters); |
470 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 488 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
471 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 489 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
472 | } | 490 | } |
473 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 491 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { |
474 | write!(f, "impl Future<Output = ")?; | 492 | write!(f, "impl Future<Output = ")?; |
475 | self.parameters[0].hir_fmt(f)?; | 493 | parameters[0].hir_fmt(f)?; |
476 | write!(f, ">")?; | 494 | write!(f, ">")?; |
477 | } | 495 | } |
478 | } | 496 | } |
479 | } | 497 | } |
480 | TypeCtor::Closure { .. } => { | 498 | Ty::Closure(.., substs) => { |
481 | let sig = self.parameters[0].callable_sig(f.db); | 499 | let sig = substs[0].callable_sig(f.db); |
482 | if let Some(sig) = sig { | 500 | if let Some(sig) = sig { |
483 | if sig.params().is_empty() { | 501 | if sig.params().is_empty() { |
484 | write!(f, "||")?; | 502 | write!(f, "||")?; |
@@ -501,44 +519,6 @@ impl HirDisplay for ApplicationTy { | |||
501 | write!(f, "{{closure}}")?; | 519 | write!(f, "{{closure}}")?; |
502 | } | 520 | } |
503 | } | 521 | } |
504 | } | ||
505 | Ok(()) | ||
506 | } | ||
507 | } | ||
508 | |||
509 | impl HirDisplay for ProjectionTy { | ||
510 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
511 | if f.should_truncate() { | ||
512 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
513 | } | ||
514 | |||
515 | let trait_ = f.db.trait_data(self.trait_(f.db)); | ||
516 | let first_parameter = self.parameters[0].into_displayable( | ||
517 | f.db, | ||
518 | f.max_size, | ||
519 | f.omit_verbose_types, | ||
520 | f.display_target, | ||
521 | ); | ||
522 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | ||
523 | if self.parameters.len() > 1 { | ||
524 | write!(f, "<")?; | ||
525 | f.write_joined(&self.parameters[1..], ", ")?; | ||
526 | write!(f, ">")?; | ||
527 | } | ||
528 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | ||
529 | Ok(()) | ||
530 | } | ||
531 | } | ||
532 | |||
533 | impl HirDisplay for Ty { | ||
534 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
535 | if f.should_truncate() { | ||
536 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
537 | } | ||
538 | |||
539 | match self { | ||
540 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | ||
541 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, | ||
542 | Ty::Placeholder(id) => { | 522 | Ty::Placeholder(id) => { |
543 | let generics = generics(f.db.upcast(), id.parent); | 523 | let generics = generics(f.db.upcast(), id.parent); |
544 | let param_data = &generics.params.types[id.local_id]; | 524 | let param_data = &generics.params.types[id.local_id]; |
@@ -557,11 +537,12 @@ impl HirDisplay for Ty { | |||
557 | } | 537 | } |
558 | } | 538 | } |
559 | } | 539 | } |
560 | Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 540 | Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, |
561 | Ty::Dyn(predicates) => { | 541 | Ty::Dyn(predicates) => { |
562 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; | 542 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; |
563 | } | 543 | } |
564 | Ty::Opaque(opaque_ty) => { | 544 | Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, |
545 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
565 | match opaque_ty.opaque_ty_id { | 546 | match opaque_ty.opaque_ty_id { |
566 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 547 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
567 | let datas = | 548 | let datas = |
@@ -585,13 +566,13 @@ impl HirDisplay for Ty { | |||
585 | } | 566 | } |
586 | write!(f, "{{unknown}}")?; | 567 | write!(f, "{{unknown}}")?; |
587 | } | 568 | } |
588 | Ty::Infer(..) => write!(f, "_")?, | 569 | Ty::InferenceVar(..) => write!(f, "_")?, |
589 | } | 570 | } |
590 | Ok(()) | 571 | Ok(()) |
591 | } | 572 | } |
592 | } | 573 | } |
593 | 574 | ||
594 | impl HirDisplay for FnSig { | 575 | impl HirDisplay for CallableSig { |
595 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 576 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
596 | write!(f, "fn(")?; | 577 | write!(f, "fn(")?; |
597 | f.write_joined(self.params(), ", ")?; | 578 | f.write_joined(self.params(), ", ")?; |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 4b683c5a7..18a4f5e8a 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -36,25 +36,15 @@ use stdx::impl_from; | |||
36 | use syntax::SmolStr; | 36 | use syntax::SmolStr; |
37 | 37 | ||
38 | use super::{ | 38 | use super::{ |
39 | primitive::{FloatTy, IntTy}, | ||
40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 39 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 40 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 41 | }; |
43 | use crate::{ | 42 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | 43 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | pub(crate) use unify::unify; | 46 | pub(crate) use unify::unify; |
48 | 47 | ||
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; | 48 | mod unify; |
59 | mod path; | 49 | mod path; |
60 | mod expr; | 50 | mod expr; |
@@ -405,7 +395,7 @@ impl<'a> InferenceContext<'a> { | |||
405 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { | 395 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { |
406 | let ty = self.resolve_ty_as_possible(ty); | 396 | let ty = self.resolve_ty_as_possible(ty); |
407 | ty.fold(&mut |ty| match ty { | 397 | ty.fold(&mut |ty| match ty { |
408 | Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), | 398 | Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), |
409 | _ => ty, | 399 | _ => ty, |
410 | }) | 400 | }) |
411 | } | 401 | } |
@@ -664,30 +654,17 @@ impl<'a> InferenceContext<'a> { | |||
664 | /// two are used for inference of literal values (e.g. `100` could be one of | 654 | /// two are used for inference of literal values (e.g. `100` could be one of |
665 | /// several integer types). | 655 | /// several integer types). |
666 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | 656 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] |
667 | pub enum InferTy { | 657 | pub struct InferenceVar { |
668 | TypeVar(unify::TypeVarId), | 658 | index: u32, |
669 | IntVar(unify::TypeVarId), | ||
670 | FloatVar(unify::TypeVarId), | ||
671 | MaybeNeverTypeVar(unify::TypeVarId), | ||
672 | } | 659 | } |
673 | 660 | ||
674 | impl InferTy { | 661 | impl InferenceVar { |
675 | fn to_inner(self) -> unify::TypeVarId { | 662 | fn to_inner(self) -> unify::TypeVarId { |
676 | match self { | 663 | unify::TypeVarId(self.index) |
677 | InferTy::TypeVar(ty) | ||
678 | | InferTy::IntVar(ty) | ||
679 | | InferTy::FloatVar(ty) | ||
680 | | InferTy::MaybeNeverTypeVar(ty) => ty, | ||
681 | } | ||
682 | } | 664 | } |
683 | 665 | ||
684 | fn fallback_value(self) -> Ty { | 666 | fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self { |
685 | match self { | 667 | InferenceVar { index } |
686 | InferTy::TypeVar(..) => Ty::Unknown, | ||
687 | InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())), | ||
688 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())), | ||
689 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), | ||
690 | } | ||
691 | } | 668 | } |
692 | } | 669 | } |
693 | 670 | ||
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c7c57cd..c33d8c61e 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -4,12 +4,13 @@ | |||
4 | //! | 4 | //! |
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use chalk_ir::TyVariableKind; | ||
7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 8 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; |
8 | use test_utils::mark; | 9 | use test_utils::mark; |
9 | 10 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; | 11 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; |
11 | 12 | ||
12 | use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; | 13 | use super::{InEnvironment, InferenceContext}; |
13 | 14 | ||
14 | impl<'a> InferenceContext<'a> { | 15 | impl<'a> InferenceContext<'a> { |
15 | /// Unify two types, but may coerce the first one to the second one | 16 | /// Unify two types, but may coerce the first one to the second one |
@@ -33,7 +34,7 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 34 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 35 | ty1.clone() |
35 | } else { | 36 | } else { |
36 | if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { | 37 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { |
37 | mark::hit!(coerce_fn_reification); | 38 | mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 39 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 40 | // pointers to have a chance at getting a match. See |
@@ -53,12 +54,11 @@ impl<'a> InferenceContext<'a> { | |||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 54 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 55 | match (&from_ty, to_ty) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 56 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { | 57 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { |
57 | let var = self.table.new_maybe_never_type_var(); | 58 | self.table.type_variable_table.set_diverging(*tv, true); |
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::Raw(m1, ..), Ty::Raw(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::Raw(m2 @ Mutability::Shared, ..)) | ||
83 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | ||
84 | from_ty = Ty::Raw(m2, substs.clone()); | ||
82 | } | 85 | } |
83 | 86 | ||
84 | // Illegal mutablity conversion | 87 | // Illegal mutability conversion |
85 | ( | 88 | (Ty::Raw(Mutability::Shared, ..), Ty::Raw(Mutability::Mut, ..)) |
86 | ty_app!(TypeCtor::RawPtr(Mutability::Shared)), | 89 | | (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false, |
87 | ty_app!(TypeCtor::RawPtr(Mutability::Mut)), | ||
88 | ) | ||
89 | | ( | ||
90 | ty_app!(TypeCtor::Ref(Mutability::Shared)), | ||
91 | ty_app!(TypeCtor::Ref(Mutability::Mut)), | ||
92 | ) => return false, | ||
93 | 90 | ||
94 | // `{function_type}` -> `fn()` | 91 | // `{function_type}` -> `fn()` |
95 | (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { | 92 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { |
96 | match from_ty.callable_sig(self.db) { | 93 | None => return false, |
97 | None => return false, | 94 | Some(sig) => { |
98 | Some(sig) => { | 95 | from_ty = Ty::fn_ptr(sig); |
99 | from_ty = Ty::fn_ptr(sig); | ||
100 | } | ||
101 | } | 96 | } |
102 | } | 97 | }, |
103 | 98 | ||
104 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | 99 | (Ty::Closure(.., substs), Ty::Function { .. }) => { |
105 | from_ty = params[0].clone(); | 100 | from_ty = substs[0].clone(); |
106 | } | 101 | } |
107 | 102 | ||
108 | _ => {} | 103 | _ => {} |
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> { | |||
115 | // Auto Deref if cannot coerce | 110 | // Auto Deref if cannot coerce |
116 | match (&from_ty, to_ty) { | 111 | match (&from_ty, to_ty) { |
117 | // FIXME: DerefMut | 112 | // FIXME: DerefMut |
118 | (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { | 113 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), |
119 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
120 | } | ||
121 | 114 | ||
122 | // Otherwise, normal unify | 115 | // Otherwise, normal unify |
123 | _ => self.unify(&from_ty, to_ty), | 116 | _ => self.unify(&from_ty, to_ty), |
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> { | |||
178 | }, | 171 | }, |
179 | ) { | 172 | ) { |
180 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); | 173 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); |
181 | match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { | 174 | let from_ty = self.resolve_ty_shallow(&derefed_ty); |
182 | // Stop when constructor matches. | 175 | // Stop when constructor matches. |
183 | (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { | 176 | if from_ty.equals_ctor(&to_ty) { |
184 | // It will not recurse to `coerce`. | 177 | // It will not recurse to `coerce`. |
185 | return self.table.unify_substs(st1, st2, 0); | 178 | return match (from_ty.substs(), to_ty.substs()) { |
186 | } | 179 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), |
187 | _ => { | 180 | (None, None) => true, |
188 | if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 181 | _ => false, |
189 | return true; | 182 | }; |
190 | } | 183 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
191 | } | 184 | return true; |
192 | } | 185 | } |
193 | } | 186 | } |
194 | 187 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index cb59a6937..7852b3d23 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::TyVariableKind; | ||
6 | use hir_def::{ | 7 | use hir_def::{ |
7 | builtin_type::Signedness, | ||
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
10 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
@@ -16,10 +16,11 @@ use test_utils::mark; | |||
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, method_resolution, op, | 18 | autoderef, method_resolution, op, |
19 | primitive::{self, UintTy}, | ||
19 | traits::{FnTrait, InEnvironment}, | 20 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 21 | utils::{generics, variant_data, Generics}, |
21 | ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, | 22 | Binders, CallableDefId, FnPointer, FnSig, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, |
22 | Rawness, Substs, TraitRef, Ty, TypeCtor, | 23 | Substs, TraitRef, Ty, |
23 | }; | 24 | }; |
24 | 25 | ||
25 | use super::{ | 26 | use super::{ |
@@ -82,10 +83,7 @@ impl<'a> InferenceContext<'a> { | |||
82 | arg_tys.push(arg); | 83 | arg_tys.push(arg); |
83 | } | 84 | } |
84 | let parameters = param_builder.build(); | 85 | let parameters = param_builder.build(); |
85 | let arg_ty = Ty::Apply(ApplicationTy { | 86 | let arg_ty = Ty::Tuple(num_args, parameters); |
86 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, | ||
87 | parameters, | ||
88 | }); | ||
89 | let substs = | 87 | let substs = |
90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 88 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
91 | 89 | ||
@@ -120,7 +118,7 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::Missing => Ty::Unknown, | 118 | Expr::Missing => Ty::Unknown, |
121 | Expr::If { condition, then_branch, else_branch } => { | 119 | Expr::If { condition, then_branch, else_branch } => { |
122 | // if let is desugared to match, so this is always simple if | 120 | // if let is desugared to match, so this is always simple if |
123 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 121 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
124 | 122 | ||
125 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 123 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
126 | let mut both_arms_diverge = Diverges::Always; | 124 | let mut both_arms_diverge = Diverges::Always; |
@@ -175,7 +173,7 @@ impl<'a> InferenceContext<'a> { | |||
175 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 173 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
176 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 174 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
177 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 175 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
178 | Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) | 176 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) |
179 | } | 177 | } |
180 | Expr::Loop { body, label } => { | 178 | Expr::Loop { body, label } => { |
181 | self.breakables.push(BreakableContext { | 179 | self.breakables.push(BreakableContext { |
@@ -193,7 +191,7 @@ impl<'a> InferenceContext<'a> { | |||
193 | if ctxt.may_break { | 191 | if ctxt.may_break { |
194 | ctxt.break_ty | 192 | ctxt.break_ty |
195 | } else { | 193 | } else { |
196 | Ty::simple(TypeCtor::Never) | 194 | Ty::Never |
197 | } | 195 | } |
198 | } | 196 | } |
199 | Expr::While { condition, body, label } => { | 197 | Expr::While { condition, body, label } => { |
@@ -203,7 +201,7 @@ impl<'a> InferenceContext<'a> { | |||
203 | label: label.map(|label| self.body[label].name.clone()), | 201 | label: label.map(|label| self.body[label].name.clone()), |
204 | }); | 202 | }); |
205 | // while let is desugared to a match loop, so this is always simple while | 203 | // while let is desugared to a match loop, so this is always simple while |
206 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 204 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 205 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 206 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
209 | // the body may not run, so it diverging doesn't mean we diverge | 207 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -250,12 +248,12 @@ impl<'a> InferenceContext<'a> { | |||
250 | None => self.table.new_type_var(), | 248 | None => self.table.new_type_var(), |
251 | }; | 249 | }; |
252 | sig_tys.push(ret_ty.clone()); | 250 | sig_tys.push(ret_ty.clone()); |
253 | let sig_ty = Ty::apply( | 251 | let sig_ty = Ty::Function(FnPointer { |
254 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 252 | num_args: sig_tys.len() - 1, |
255 | Substs(sig_tys.clone().into()), | 253 | sig: FnSig { variadic: false }, |
256 | ); | 254 | substs: Substs(sig_tys.clone().into()), |
257 | let closure_ty = | 255 | }); |
258 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); | 256 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); |
259 | 257 | ||
260 | // Eagerly try to relate the closure type with the expected | 258 | // Eagerly try to relate the closure type with the expected |
261 | // type, otherwise we often won't have enough information to | 259 | // type, otherwise we often won't have enough information to |
@@ -306,11 +304,8 @@ impl<'a> InferenceContext<'a> { | |||
306 | Expr::Match { expr, arms } => { | 304 | Expr::Match { expr, arms } => { |
307 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 305 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
308 | 306 | ||
309 | let mut result_ty = if arms.is_empty() { | 307 | let mut result_ty = |
310 | Ty::simple(TypeCtor::Never) | 308 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
311 | } else { | ||
312 | self.table.new_type_var() | ||
313 | }; | ||
314 | 309 | ||
315 | let matchee_diverges = self.diverges; | 310 | let matchee_diverges = self.diverges; |
316 | let mut all_arms_diverge = Diverges::Always; | 311 | let mut all_arms_diverge = Diverges::Always; |
@@ -321,7 +316,7 @@ impl<'a> InferenceContext<'a> { | |||
321 | if let Some(guard_expr) = arm.guard { | 316 | if let Some(guard_expr) = arm.guard { |
322 | self.infer_expr( | 317 | self.infer_expr( |
323 | guard_expr, | 318 | guard_expr, |
324 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 319 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
325 | ); | 320 | ); |
326 | } | 321 | } |
327 | 322 | ||
@@ -339,7 +334,7 @@ impl<'a> InferenceContext<'a> { | |||
339 | 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); |
340 | 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) |
341 | } | 336 | } |
342 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 337 | Expr::Continue { .. } => Ty::Never, |
343 | Expr::Break { expr, label } => { | 338 | Expr::Break { expr, label } => { |
344 | let val_ty = if let Some(expr) = expr { | 339 | let val_ty = if let Some(expr) = expr { |
345 | self.infer_expr(*expr, &Expectation::none()) | 340 | self.infer_expr(*expr, &Expectation::none()) |
@@ -364,8 +359,7 @@ impl<'a> InferenceContext<'a> { | |||
364 | expr: tgt_expr, | 359 | expr: tgt_expr, |
365 | }); | 360 | }); |
366 | } | 361 | } |
367 | 362 | Ty::Never | |
368 | Ty::simple(TypeCtor::Never) | ||
369 | } | 363 | } |
370 | Expr::Return { expr } => { | 364 | Expr::Return { expr } => { |
371 | if let Some(expr) = expr { | 365 | if let Some(expr) = expr { |
@@ -374,14 +368,14 @@ impl<'a> InferenceContext<'a> { | |||
374 | let unit = Ty::unit(); | 368 | let unit = Ty::unit(); |
375 | self.coerce(&unit, &self.return_ty.clone()); | 369 | self.coerce(&unit, &self.return_ty.clone()); |
376 | } | 370 | } |
377 | Ty::simple(TypeCtor::Never) | 371 | Ty::Never |
378 | } | 372 | } |
379 | Expr::Yield { expr } => { | 373 | Expr::Yield { expr } => { |
380 | // FIXME: track yield type for coercion | 374 | // FIXME: track yield type for coercion |
381 | if let Some(expr) = expr { | 375 | if let Some(expr) = expr { |
382 | self.infer_expr(*expr, &Expectation::none()); | 376 | self.infer_expr(*expr, &Expectation::none()); |
383 | } | 377 | } |
384 | Ty::simple(TypeCtor::Never) | 378 | Ty::Never |
385 | } | 379 | } |
386 | Expr::RecordLit { path, fields, spread } => { | 380 | Expr::RecordLit { path, fields, spread } => { |
387 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 381 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -391,7 +385,7 @@ impl<'a> InferenceContext<'a> { | |||
391 | 385 | ||
392 | self.unify(&ty, &expected.ty); | 386 | self.unify(&ty, &expected.ty); |
393 | 387 | ||
394 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 388 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
395 | 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(); |
396 | 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)); |
397 | for (field_idx, field) in fields.iter().enumerate() { | 391 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -430,30 +424,23 @@ impl<'a> InferenceContext<'a> { | |||
430 | }, | 424 | }, |
431 | ) | 425 | ) |
432 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 426 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
433 | Ty::Apply(a_ty) => match a_ty.ctor { | 427 | Ty::Tuple(_, substs) => { |
434 | TypeCtor::Tuple { .. } => name | 428 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
435 | .as_tuple_index() | 429 | } |
436 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 430 | Ty::Adt(AdtId::StructId(s), parameters) => { |
437 | TypeCtor::Adt(AdtId::StructId(s)) => { | 431 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
438 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 432 | let field = FieldId { parent: s.into(), local_id }; |
439 | let field = FieldId { parent: s.into(), local_id }; | 433 | self.write_field_resolution(tgt_expr, field); |
440 | self.write_field_resolution(tgt_expr, field); | 434 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
441 | self.db.field_types(s.into())[field.local_id] | 435 | }) |
442 | .clone() | 436 | } |
443 | .subst(&a_ty.parameters) | 437 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
444 | }) | 438 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
445 | } | 439 | let field = FieldId { parent: u.into(), local_id }; |
446 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 440 | self.write_field_resolution(tgt_expr, field); |
447 | 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) |
448 | let field = FieldId { parent: u.into(), local_id }; | 442 | }) |
449 | self.write_field_resolution(tgt_expr, field); | 443 | } |
450 | self.db.field_types(u.into())[field.local_id] | ||
451 | .clone() | ||
452 | .subst(&a_ty.parameters) | ||
453 | }) | ||
454 | } | ||
455 | _ => None, | ||
456 | }, | ||
457 | _ => None, | 444 | _ => None, |
458 | }) | 445 | }) |
459 | .unwrap_or(Ty::Unknown); | 446 | .unwrap_or(Ty::Unknown); |
@@ -491,19 +478,24 @@ impl<'a> InferenceContext<'a> { | |||
491 | Expectation::none() | 478 | Expectation::none() |
492 | }; | 479 | }; |
493 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 480 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
494 | let ty = match rawness { | 481 | match rawness { |
495 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 482 | Rawness::RawPtr => Ty::Raw(*mutability, Substs::single(inner_ty)), |
496 | Rawness::Ref => TypeCtor::Ref(*mutability), | 483 | Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)), |
497 | }; | 484 | } |
498 | Ty::apply_one(ty, inner_ty) | ||
499 | } | 485 | } |
500 | Expr::Box { expr } => { | 486 | Expr::Box { expr } => { |
501 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 487 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
502 | if let Some(box_) = self.resolve_boxed_box() { | 488 | if let Some(box_) = self.resolve_boxed_box() { |
503 | 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()); |
504 | sb = sb.push(inner_ty); | 490 | sb = sb.push(inner_ty); |
491 | match self.db.generic_defaults(box_.into()).as_ref() { | ||
492 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | ||
493 | sb = sb.push(alloc_ty.value.clone()); | ||
494 | } | ||
495 | _ => (), | ||
496 | } | ||
505 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 497 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
506 | Ty::apply(TypeCtor::Adt(box_), sb.build()) | 498 | Ty::Adt(box_, sb.build()) |
507 | } else { | 499 | } else { |
508 | Ty::Unknown | 500 | Ty::Unknown |
509 | } | 501 | } |
@@ -533,13 +525,11 @@ impl<'a> InferenceContext<'a> { | |||
533 | UnaryOp::Neg => { | 525 | UnaryOp::Neg => { |
534 | match &inner_ty { | 526 | match &inner_ty { |
535 | // Fast path for builtins | 527 | // Fast path for builtins |
536 | Ty::Apply(ApplicationTy { | 528 | Ty::Scalar(Scalar::Int(_)) |
537 | ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), | 529 | | Ty::Scalar(Scalar::Uint(_)) |
538 | .. | 530 | | Ty::Scalar(Scalar::Float(_)) |
539 | }) | 531 | | Ty::InferenceVar(_, TyVariableKind::Integer) |
540 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | 532 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
541 | | Ty::Infer(InferTy::IntVar(..)) | ||
542 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | ||
543 | // Otherwise we resolve via the std::ops::Neg trait | 533 | // Otherwise we resolve via the std::ops::Neg trait |
544 | _ => self | 534 | _ => self |
545 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 535 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
@@ -548,9 +538,10 @@ impl<'a> InferenceContext<'a> { | |||
548 | UnaryOp::Not => { | 538 | UnaryOp::Not => { |
549 | match &inner_ty { | 539 | match &inner_ty { |
550 | // Fast path for builtins | 540 | // Fast path for builtins |
551 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) | 541 | Ty::Scalar(Scalar::Bool) |
552 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) | 542 | | Ty::Scalar(Scalar::Int(_)) |
553 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 543 | | Ty::Scalar(Scalar::Uint(_)) |
544 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | ||
554 | // Otherwise we resolve via the std::ops::Not trait | 545 | // Otherwise we resolve via the std::ops::Not trait |
555 | _ => self | 546 | _ => self |
556 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 547 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -561,7 +552,7 @@ impl<'a> InferenceContext<'a> { | |||
561 | Expr::BinaryOp { lhs, rhs, op } => match op { | 552 | Expr::BinaryOp { lhs, rhs, op } => match op { |
562 | Some(op) => { | 553 | Some(op) => { |
563 | let lhs_expectation = match op { | 554 | let lhs_expectation = match op { |
564 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 555 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
565 | _ => Expectation::none(), | 556 | _ => Expectation::none(), |
566 | }; | 557 | }; |
567 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 558 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -592,31 +583,31 @@ impl<'a> InferenceContext<'a> { | |||
592 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 583 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
593 | match (range_type, lhs_ty, rhs_ty) { | 584 | match (range_type, lhs_ty, rhs_ty) { |
594 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 585 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
595 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 586 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
596 | None => Ty::Unknown, | 587 | None => Ty::Unknown, |
597 | }, | 588 | }, |
598 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 589 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
599 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 590 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
600 | None => Ty::Unknown, | 591 | None => Ty::Unknown, |
601 | }, | 592 | }, |
602 | (RangeOp::Inclusive, None, Some(ty)) => { | 593 | (RangeOp::Inclusive, None, Some(ty)) => { |
603 | match self.resolve_range_to_inclusive() { | 594 | match self.resolve_range_to_inclusive() { |
604 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 595 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
605 | None => Ty::Unknown, | 596 | None => Ty::Unknown, |
606 | } | 597 | } |
607 | } | 598 | } |
608 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 599 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
609 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 600 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
610 | None => Ty::Unknown, | 601 | None => Ty::Unknown, |
611 | }, | 602 | }, |
612 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 603 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
613 | match self.resolve_range_inclusive() { | 604 | match self.resolve_range_inclusive() { |
614 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 605 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
615 | None => Ty::Unknown, | 606 | None => Ty::Unknown, |
616 | } | 607 | } |
617 | } | 608 | } |
618 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 609 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
619 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 610 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
620 | None => Ty::Unknown, | 611 | None => Ty::Unknown, |
621 | }, | 612 | }, |
622 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 613 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -650,7 +641,7 @@ impl<'a> InferenceContext<'a> { | |||
650 | } | 641 | } |
651 | Expr::Tuple { exprs } => { | 642 | Expr::Tuple { exprs } => { |
652 | let mut tys = match &expected.ty { | 643 | let mut tys = match &expected.ty { |
653 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 644 | Ty::Tuple(_, substs) => substs |
654 | .iter() | 645 | .iter() |
655 | .cloned() | 646 | .cloned() |
656 | .chain(repeat_with(|| self.table.new_type_var())) | 647 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -663,15 +654,11 @@ impl<'a> InferenceContext<'a> { | |||
663 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 654 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
664 | } | 655 | } |
665 | 656 | ||
666 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 657 | Ty::Tuple(tys.len(), Substs(tys.into())) |
667 | } | 658 | } |
668 | Expr::Array(array) => { | 659 | Expr::Array(array) => { |
669 | let elem_ty = match &expected.ty { | 660 | let elem_ty = match &expected.ty { |
670 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 661 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), |
671 | #[allow(unreachable_patterns)] | ||
672 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | ||
673 | st.as_single().clone() | ||
674 | } | ||
675 | _ => self.table.new_type_var(), | 662 | _ => self.table.new_type_var(), |
676 | }; | 663 | }; |
677 | 664 | ||
@@ -688,30 +675,38 @@ impl<'a> InferenceContext<'a> { | |||
688 | ); | 675 | ); |
689 | self.infer_expr( | 676 | self.infer_expr( |
690 | *repeat, | 677 | *repeat, |
691 | &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), | 678 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
692 | ); | 679 | ); |
693 | } | 680 | } |
694 | } | 681 | } |
695 | 682 | ||
696 | Ty::apply_one(TypeCtor::Array, elem_ty) | 683 | Ty::Array(Substs::single(elem_ty)) |
697 | } | 684 | } |
698 | Expr::Literal(lit) => match lit { | 685 | Expr::Literal(lit) => match lit { |
699 | Literal::Bool(..) => Ty::simple(TypeCtor::Bool), | 686 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
700 | Literal::String(..) => { | 687 | Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)), |
701 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
702 | } | ||
703 | Literal::ByteString(..) => { | 688 | Literal::ByteString(..) => { |
704 | let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); | 689 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
705 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 690 | let array_type = Ty::Array(Substs::single(byte_type)); |
706 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 691 | Ty::Ref(Mutability::Shared, Substs::single(array_type)) |
707 | } | 692 | } |
708 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 693 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
709 | Literal::Int(_v, ty) => match ty { | 694 | Literal::Int(_v, ty) => match ty { |
710 | Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), | 695 | Some(int_ty) => { |
696 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | ||
697 | } | ||
698 | None => self.table.new_integer_var(), | ||
699 | }, | ||
700 | Literal::Uint(_v, ty) => match ty { | ||
701 | Some(int_ty) => { | ||
702 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | ||
703 | } | ||
711 | None => self.table.new_integer_var(), | 704 | None => self.table.new_integer_var(), |
712 | }, | 705 | }, |
713 | Literal::Float(_v, ty) => match ty { | 706 | Literal::Float(_v, ty) => match ty { |
714 | Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), | 707 | Some(float_ty) => { |
708 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | ||
709 | } | ||
715 | None => self.table.new_float_var(), | 710 | None => self.table.new_float_var(), |
716 | }, | 711 | }, |
717 | }, | 712 | }, |
@@ -767,7 +762,7 @@ impl<'a> InferenceContext<'a> { | |||
767 | // `!`). | 762 | // `!`). |
768 | if self.diverges.is_always() { | 763 | if self.diverges.is_always() { |
769 | // we don't even make an attempt at coercion | 764 | // we don't even make an attempt at coercion |
770 | self.table.new_maybe_never_type_var() | 765 | self.table.new_maybe_never_var() |
771 | } else { | 766 | } else { |
772 | self.coerce(&Ty::unit(), expected.coercion_target()); | 767 | self.coerce(&Ty::unit(), expected.coercion_target()); |
773 | Ty::unit() | 768 | Ty::unit() |
@@ -824,7 +819,7 @@ impl<'a> InferenceContext<'a> { | |||
824 | // Apply autoref so the below unification works correctly | 819 | // Apply autoref so the below unification works correctly |
825 | // FIXME: return correct autorefs from lookup_method | 820 | // FIXME: return correct autorefs from lookup_method |
826 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 821 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
827 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 822 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
828 | _ => derefed_receiver_ty, | 823 | _ => derefed_receiver_ty, |
829 | }; | 824 | }; |
830 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 825 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -901,30 +896,26 @@ impl<'a> InferenceContext<'a> { | |||
901 | } | 896 | } |
902 | 897 | ||
903 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 898 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
904 | if let Ty::Apply(a_ty) = callable_ty { | 899 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
905 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 900 | let generic_predicates = self.db.generic_predicates(def.into()); |
906 | let generic_predicates = self.db.generic_predicates(def.into()); | 901 | for predicate in generic_predicates.iter() { |
907 | for predicate in generic_predicates.iter() { | 902 | let predicate = predicate.clone().subst(parameters); |
908 | let predicate = predicate.clone().subst(&a_ty.parameters); | 903 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
909 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 904 | self.obligations.push(obligation); |
910 | self.obligations.push(obligation); | ||
911 | } | ||
912 | } | 905 | } |
913 | // add obligation for trait implementation, if this is a trait method | 906 | } |
914 | match def { | 907 | // add obligation for trait implementation, if this is a trait method |
915 | CallableDefId::FunctionId(f) => { | 908 | match def { |
916 | if let AssocContainerId::TraitId(trait_) = | 909 | CallableDefId::FunctionId(f) => { |
917 | f.lookup(self.db.upcast()).container | 910 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
918 | { | 911 | { |
919 | // construct a TraitDef | 912 | // construct a TraitDef |
920 | let substs = a_ty | 913 | let substs = |
921 | .parameters | 914 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
922 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 915 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
923 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
924 | } | ||
925 | } | 916 | } |
926 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
927 | } | 917 | } |
918 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
928 | } | 919 | } |
929 | } | 920 | } |
930 | } | 921 | } |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index d974f805b..a318e47f3 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -13,7 +13,7 @@ use hir_expand::name::Name; | |||
13 | use test_utils::mark; | 13 | use test_utils::mark; |
14 | 14 | ||
15 | use super::{BindingMode, Expectation, InferenceContext}; | 15 | use super::{BindingMode, Expectation, InferenceContext}; |
16 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; | 16 | use crate::{utils::variant_data, Substs, Ty}; |
17 | 17 | ||
18 | impl<'a> InferenceContext<'a> { | 18 | impl<'a> InferenceContext<'a> { |
19 | fn infer_tuple_struct_pat( | 19 | fn infer_tuple_struct_pat( |
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> { | |||
32 | } | 32 | } |
33 | self.unify(&ty, expected); | 33 | self.unify(&ty, expected); |
34 | 34 | ||
35 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 35 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
36 | 36 | ||
37 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 37 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
38 | let (pre, post) = match ellipsis { | 38 | let (pre, post) = match ellipsis { |
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> { | |||
71 | 71 | ||
72 | self.unify(&ty, expected); | 72 | self.unify(&ty, expected); |
73 | 73 | ||
74 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 74 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
75 | 75 | ||
76 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 76 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
77 | for subpat in subpats { | 77 | for subpat in subpats { |
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> { | |||
138 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); | 138 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); |
139 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | 139 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); |
140 | 140 | ||
141 | Ty::apply( | 141 | Ty::Tuple(inner_tys.len(), Substs(inner_tys.into())) |
142 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | ||
143 | Substs(inner_tys.into()), | ||
144 | ) | ||
145 | } | 142 | } |
146 | Pat::Or(ref pats) => { | 143 | Pat::Or(ref pats) => { |
147 | if let Some((first_pat, rest)) = pats.split_first() { | 144 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> { | |||
165 | _ => &Ty::Unknown, | 162 | _ => &Ty::Unknown, |
166 | }; | 163 | }; |
167 | let subty = self.infer_pat(*pat, expectation, default_bm); | 164 | let subty = self.infer_pat(*pat, expectation, default_bm); |
168 | Ty::apply_one(TypeCtor::Ref(*mutability), subty) | 165 | Ty::Ref(*mutability, Substs::single(subty)) |
169 | } | 166 | } |
170 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 167 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
171 | p.as_ref(), | 168 | p.as_ref(), |
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> { | |||
198 | 195 | ||
199 | let bound_ty = match mode { | 196 | let bound_ty = match mode { |
200 | BindingMode::Ref(mutability) => { | 197 | BindingMode::Ref(mutability) => { |
201 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) | 198 | Ty::Ref(mutability, Substs::single(inner_ty.clone())) |
202 | } | 199 | } |
203 | BindingMode::Move => inner_ty.clone(), | 200 | BindingMode::Move => inner_ty.clone(), |
204 | }; | 201 | }; |
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> { | |||
207 | return inner_ty; | 204 | return inner_ty; |
208 | } | 205 | } |
209 | Pat::Slice { prefix, slice, suffix } => { | 206 | Pat::Slice { prefix, slice, suffix } => { |
210 | let (container_ty, elem_ty) = match &expected { | 207 | let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { |
211 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), | 208 | Ty::Array(st) => (Ty::Array, st.as_single().clone()), |
212 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), | 209 | Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), |
213 | _ => (TypeCtor::Slice, Ty::Unknown), | 210 | _ => (Ty::Slice, Ty::Unknown), |
214 | }; | 211 | }; |
215 | 212 | ||
216 | for pat_id in prefix.iter().chain(suffix) { | 213 | for pat_id in prefix.iter().chain(suffix) { |
217 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 214 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
218 | } | 215 | } |
219 | 216 | ||
220 | let pat_ty = Ty::apply_one(container_ty, elem_ty); | 217 | let pat_ty = container_ty(Substs::single(elem_ty)); |
221 | if let Some(slice_pat_id) = slice { | 218 | if let Some(slice_pat_id) = slice { |
222 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 219 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
223 | } | 220 | } |
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> { | |||
239 | }; | 236 | }; |
240 | 237 | ||
241 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 238 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); |
242 | Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) | 239 | Ty::Adt(box_adt, Substs::single(inner_ty)) |
243 | } | 240 | } |
244 | None => Ty::Unknown, | 241 | None => Ty::Unknown, |
245 | }, | 242 | }, |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 76984242e..99a89a7f3 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -2,14 +2,15 @@ | |||
2 | 2 | ||
3 | use std::borrow::Cow; | 3 | use std::borrow::Cow; |
4 | 4 | ||
5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind}; | ||
5 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
6 | 7 | ||
7 | use test_utils::mark; | 8 | use test_utils::mark; |
8 | 9 | ||
9 | use super::{InferenceContext, Obligation}; | 10 | use super::{InferenceContext, Obligation}; |
10 | use crate::{ | 11 | use crate::{ |
11 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, | 12 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, |
12 | TyKind, TypeCtor, TypeWalk, | 13 | Substs, Ty, TypeWalk, |
13 | }; | 14 | }; |
14 | 15 | ||
15 | impl<'a> InferenceContext<'a> { | 16 | impl<'a> InferenceContext<'a> { |
@@ -26,7 +27,7 @@ where | |||
26 | 'a: 'b, | 27 | 'a: 'b, |
27 | { | 28 | { |
28 | ctx: &'b mut InferenceContext<'a>, | 29 | ctx: &'b mut InferenceContext<'a>, |
29 | free_vars: Vec<InferTy>, | 30 | free_vars: Vec<(InferenceVar, TyVariableKind)>, |
30 | /// A stack of type variables that is used to detect recursive types (which | 31 | /// A stack of type variables that is used to detect recursive types (which |
31 | /// are an error, but we need to protect against them to avoid stack | 32 | /// are an error, but we need to protect against them to avoid stack |
32 | /// overflows). | 33 | /// overflows). |
@@ -36,17 +37,14 @@ where | |||
36 | #[derive(Debug)] | 37 | #[derive(Debug)] |
37 | pub(super) struct Canonicalized<T> { | 38 | pub(super) struct Canonicalized<T> { |
38 | pub(super) value: Canonical<T>, | 39 | pub(super) value: Canonical<T>, |
39 | free_vars: Vec<InferTy>, | 40 | free_vars: Vec<(InferenceVar, TyVariableKind)>, |
40 | } | 41 | } |
41 | 42 | ||
42 | impl<'a, 'b> Canonicalizer<'a, 'b> | 43 | impl<'a, 'b> Canonicalizer<'a, 'b> { |
43 | where | 44 | fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize { |
44 | 'a: 'b, | 45 | self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| { |
45 | { | ||
46 | fn add(&mut self, free_var: InferTy) -> usize { | ||
47 | self.free_vars.iter().position(|&v| v == free_var).unwrap_or_else(|| { | ||
48 | let next_index = self.free_vars.len(); | 46 | let next_index = self.free_vars.len(); |
49 | self.free_vars.push(free_var); | 47 | self.free_vars.push((free_var, kind)); |
50 | next_index | 48 | next_index |
51 | }) | 49 | }) |
52 | } | 50 | } |
@@ -54,11 +52,11 @@ where | |||
54 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 52 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
55 | t.fold_binders( | 53 | t.fold_binders( |
56 | &mut |ty, binders| match ty { | 54 | &mut |ty, binders| match ty { |
57 | Ty::Infer(tv) => { | 55 | Ty::InferenceVar(var, kind) => { |
58 | let inner = tv.to_inner(); | 56 | let inner = var.to_inner(); |
59 | if self.var_stack.contains(&inner) { | 57 | if self.var_stack.contains(&inner) { |
60 | // recursive type | 58 | // recursive type |
61 | return tv.fallback_value(); | 59 | return self.ctx.table.type_variable_table.fallback_value(var, kind); |
62 | } | 60 | } |
63 | if let Some(known_ty) = | 61 | if let Some(known_ty) = |
64 | self.ctx.table.var_unification_table.inlined_probe_value(inner).known() | 62 | self.ctx.table.var_unification_table.inlined_probe_value(inner).known() |
@@ -69,14 +67,8 @@ where | |||
69 | result | 67 | result |
70 | } else { | 68 | } else { |
71 | let root = self.ctx.table.var_unification_table.find(inner); | 69 | let root = self.ctx.table.var_unification_table.find(inner); |
72 | let free_var = match tv { | 70 | let position = self.add(InferenceVar::from_inner(root), kind); |
73 | InferTy::TypeVar(_) => InferTy::TypeVar(root), | 71 | Ty::BoundVar(BoundVar::new(binders, position)) |
74 | InferTy::IntVar(_) => InferTy::IntVar(root), | ||
75 | InferTy::FloatVar(_) => InferTy::FloatVar(root), | ||
76 | InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root), | ||
77 | }; | ||
78 | let position = self.add(free_var); | ||
79 | Ty::Bound(BoundVar::new(binders, position)) | ||
80 | } | 72 | } |
81 | } | 73 | } |
82 | _ => ty, | 74 | _ => ty, |
@@ -86,19 +78,7 @@ where | |||
86 | } | 78 | } |
87 | 79 | ||
88 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { | 80 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { |
89 | let kinds = self | 81 | let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); |
90 | .free_vars | ||
91 | .iter() | ||
92 | .map(|v| match v { | ||
93 | // mapping MaybeNeverTypeVar to the same kind as general ones | ||
94 | // should be fine, because as opposed to int or float type vars, | ||
95 | // they don't restrict what kind of type can go into them, they | ||
96 | // just affect fallback. | ||
97 | InferTy::TypeVar(_) | InferTy::MaybeNeverTypeVar(_) => TyKind::General, | ||
98 | InferTy::IntVar(_) => TyKind::Integer, | ||
99 | InferTy::FloatVar(_) => TyKind::Float, | ||
100 | }) | ||
101 | .collect(); | ||
102 | Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } | 82 | Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } |
103 | } | 83 | } |
104 | 84 | ||
@@ -130,9 +110,10 @@ impl<T> Canonicalized<T> { | |||
130 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 110 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
131 | ty.walk_mut_binders( | 111 | ty.walk_mut_binders( |
132 | &mut |ty, binders| { | 112 | &mut |ty, binders| { |
133 | if let &mut Ty::Bound(bound) = ty { | 113 | if let &mut Ty::BoundVar(bound) = ty { |
134 | if bound.debruijn >= binders { | 114 | if bound.debruijn >= binders { |
135 | *ty = Ty::Infer(self.free_vars[bound.index]); | 115 | let (v, k) = self.free_vars[bound.index]; |
116 | *ty = Ty::InferenceVar(v, k); | ||
136 | } | 117 | } |
137 | } | 118 | } |
138 | }, | 119 | }, |
@@ -152,18 +133,18 @@ impl<T> Canonicalized<T> { | |||
152 | .kinds | 133 | .kinds |
153 | .iter() | 134 | .iter() |
154 | .map(|k| match k { | 135 | .map(|k| match k { |
155 | TyKind::General => ctx.table.new_type_var(), | 136 | TyVariableKind::General => ctx.table.new_type_var(), |
156 | TyKind::Integer => ctx.table.new_integer_var(), | 137 | TyVariableKind::Integer => ctx.table.new_integer_var(), |
157 | TyKind::Float => ctx.table.new_float_var(), | 138 | TyVariableKind::Float => ctx.table.new_float_var(), |
158 | }) | 139 | }) |
159 | .collect(), | 140 | .collect(), |
160 | ); | 141 | ); |
161 | for (i, ty) in solution.value.into_iter().enumerate() { | 142 | for (i, ty) in solution.value.into_iter().enumerate() { |
162 | let var = self.free_vars[i]; | 143 | let (v, k) = self.free_vars[i]; |
163 | // eagerly replace projections in the type; we may be getting types | 144 | // eagerly replace projections in the type; we may be getting types |
164 | // e.g. from where clauses where this hasn't happened yet | 145 | // e.g. from where clauses where this hasn't happened yet |
165 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); | 146 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); |
166 | ctx.table.unify(&Ty::Infer(var), &ty); | 147 | ctx.table.unify(&Ty::InferenceVar(v, k), &ty); |
167 | } | 148 | } |
168 | } | 149 | } |
169 | } | 150 | } |
@@ -187,7 +168,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
187 | // (kind of hacky) | 168 | // (kind of hacky) |
188 | for (i, var) in vars.iter().enumerate() { | 169 | for (i, var) in vars.iter().enumerate() { |
189 | if &*table.resolve_ty_shallow(var) == var { | 170 | if &*table.resolve_ty_shallow(var) == var { |
190 | table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); | 171 | table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); |
191 | } | 172 | } |
192 | } | 173 | } |
193 | Some( | 174 | Some( |
@@ -198,31 +179,73 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
198 | } | 179 | } |
199 | 180 | ||
200 | #[derive(Clone, Debug)] | 181 | #[derive(Clone, Debug)] |
182 | pub(super) struct TypeVariableTable { | ||
183 | inner: Vec<TypeVariableData>, | ||
184 | } | ||
185 | |||
186 | impl TypeVariableTable { | ||
187 | fn push(&mut self, data: TypeVariableData) { | ||
188 | self.inner.push(data); | ||
189 | } | ||
190 | |||
191 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { | ||
192 | self.inner[iv.to_inner().0 as usize].diverging = diverging; | ||
193 | } | ||
194 | |||
195 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { | ||
196 | self.inner[iv.to_inner().0 as usize].diverging | ||
197 | } | ||
198 | |||
199 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | ||
200 | match kind { | ||
201 | _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, | ||
202 | TyVariableKind::General => Ty::Unknown, | ||
203 | TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), | ||
204 | TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | |||
209 | #[derive(Copy, Clone, Debug)] | ||
210 | pub(crate) struct TypeVariableData { | ||
211 | diverging: bool, | ||
212 | } | ||
213 | |||
214 | #[derive(Clone, Debug)] | ||
201 | pub(crate) struct InferenceTable { | 215 | pub(crate) struct InferenceTable { |
202 | pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, | 216 | pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, |
217 | pub(super) type_variable_table: TypeVariableTable, | ||
203 | } | 218 | } |
204 | 219 | ||
205 | impl InferenceTable { | 220 | impl InferenceTable { |
206 | pub(crate) fn new() -> Self { | 221 | pub(crate) fn new() -> Self { |
207 | InferenceTable { var_unification_table: InPlaceUnificationTable::new() } | 222 | InferenceTable { |
223 | var_unification_table: InPlaceUnificationTable::new(), | ||
224 | type_variable_table: TypeVariableTable { inner: Vec::new() }, | ||
225 | } | ||
226 | } | ||
227 | |||
228 | fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty { | ||
229 | self.type_variable_table.push(TypeVariableData { diverging }); | ||
230 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | ||
231 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | ||
232 | Ty::InferenceVar(InferenceVar::from_inner(key), kind) | ||
208 | } | 233 | } |
209 | 234 | ||
210 | pub(crate) fn new_type_var(&mut self) -> Ty { | 235 | pub(crate) fn new_type_var(&mut self) -> Ty { |
211 | Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 236 | self.new_var(TyVariableKind::General, false) |
212 | } | 237 | } |
213 | 238 | ||
214 | pub(crate) fn new_integer_var(&mut self) -> Ty { | 239 | pub(crate) fn new_integer_var(&mut self) -> Ty { |
215 | Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 240 | self.new_var(TyVariableKind::Integer, false) |
216 | } | 241 | } |
217 | 242 | ||
218 | pub(crate) fn new_float_var(&mut self) -> Ty { | 243 | pub(crate) fn new_float_var(&mut self) -> Ty { |
219 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 244 | self.new_var(TyVariableKind::Float, false) |
220 | } | 245 | } |
221 | 246 | ||
222 | pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty { | 247 | pub(crate) fn new_maybe_never_var(&mut self) -> Ty { |
223 | Ty::Infer(InferTy::MaybeNeverTypeVar( | 248 | self.new_var(TyVariableKind::General, true) |
224 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
225 | )) | ||
226 | } | 249 | } |
227 | 250 | ||
228 | pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 251 | pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
@@ -257,12 +280,14 @@ impl InferenceTable { | |||
257 | // try to resolve type vars first | 280 | // try to resolve type vars first |
258 | let ty1 = self.resolve_ty_shallow(ty1); | 281 | let ty1 = self.resolve_ty_shallow(ty1); |
259 | let ty2 = self.resolve_ty_shallow(ty2); | 282 | let ty2 = self.resolve_ty_shallow(ty2); |
260 | match (&*ty1, &*ty2) { | 283 | if ty1.equals_ctor(&ty2) { |
261 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { | 284 | match (ty1.substs(), ty2.substs()) { |
262 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) | 285 | (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), |
286 | (None, None) => true, | ||
287 | _ => false, | ||
263 | } | 288 | } |
264 | 289 | } else { | |
265 | _ => self.unify_inner_trivial(&ty1, &ty2, depth), | 290 | self.unify_inner_trivial(&ty1, &ty2, depth) |
266 | } | 291 | } |
267 | } | 292 | } |
268 | 293 | ||
@@ -281,31 +306,46 @@ impl InferenceTable { | |||
281 | true | 306 | true |
282 | } | 307 | } |
283 | 308 | ||
284 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 309 | ( |
285 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 310 | Ty::InferenceVar(tv1, TyVariableKind::General), |
286 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) | 311 | Ty::InferenceVar(tv2, TyVariableKind::General), |
312 | ) | ||
287 | | ( | 313 | | ( |
288 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), | 314 | Ty::InferenceVar(tv1, TyVariableKind::Integer), |
289 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), | 315 | Ty::InferenceVar(tv2, TyVariableKind::Integer), |
290 | ) => { | 316 | ) |
317 | | ( | ||
318 | Ty::InferenceVar(tv1, TyVariableKind::Float), | ||
319 | Ty::InferenceVar(tv2, TyVariableKind::Float), | ||
320 | ) if self.type_variable_table.is_diverging(*tv1) | ||
321 | == self.type_variable_table.is_diverging(*tv2) => | ||
322 | { | ||
291 | // both type vars are unknown since we tried to resolve them | 323 | // both type vars are unknown since we tried to resolve them |
292 | self.var_unification_table.union(*tv1, *tv2); | 324 | self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); |
293 | true | 325 | true |
294 | } | 326 | } |
295 | 327 | ||
296 | // The order of MaybeNeverTypeVar matters here. | 328 | // The order of MaybeNeverTypeVar matters here. |
297 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | 329 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. |
298 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | 330 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. |
299 | (Ty::Infer(InferTy::TypeVar(tv)), other) | 331 | (Ty::InferenceVar(tv, TyVariableKind::General), other) |
300 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | 332 | | (other, Ty::InferenceVar(tv, TyVariableKind::General)) |
301 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) | 333 | | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_))) |
302 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) | 334 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer)) |
303 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) | 335 | | ( |
304 | | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) | 336 | Ty::InferenceVar(tv, TyVariableKind::Integer), |
305 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) | 337 | other @ Ty::Scalar(Scalar::Uint(_)), |
306 | | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { | 338 | ) |
339 | | ( | ||
340 | other @ Ty::Scalar(Scalar::Uint(_)), | ||
341 | Ty::InferenceVar(tv, TyVariableKind::Integer), | ||
342 | ) | ||
343 | | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) | ||
344 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => | ||
345 | { | ||
307 | // the type var is unknown since we tried to resolve it | 346 | // the type var is unknown since we tried to resolve it |
308 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | 347 | self.var_unification_table |
348 | .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); | ||
309 | true | 349 | true |
310 | } | 350 | } |
311 | 351 | ||
@@ -350,7 +390,7 @@ impl InferenceTable { | |||
350 | mark::hit!(type_var_resolves_to_int_var); | 390 | mark::hit!(type_var_resolves_to_int_var); |
351 | } | 391 | } |
352 | match &*ty { | 392 | match &*ty { |
353 | Ty::Infer(tv) => { | 393 | Ty::InferenceVar(tv, _) => { |
354 | let inner = tv.to_inner(); | 394 | let inner = tv.to_inner(); |
355 | match self.var_unification_table.inlined_probe_value(inner).known() { | 395 | match self.var_unification_table.inlined_probe_value(inner).known() { |
356 | Some(known_ty) => { | 396 | Some(known_ty) => { |
@@ -373,12 +413,12 @@ impl InferenceTable { | |||
373 | /// known type. | 413 | /// known type. |
374 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 414 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
375 | ty.fold(&mut |ty| match ty { | 415 | ty.fold(&mut |ty| match ty { |
376 | Ty::Infer(tv) => { | 416 | Ty::InferenceVar(tv, kind) => { |
377 | let inner = tv.to_inner(); | 417 | let inner = tv.to_inner(); |
378 | if tv_stack.contains(&inner) { | 418 | if tv_stack.contains(&inner) { |
379 | mark::hit!(type_var_cycles_resolve_as_possible); | 419 | mark::hit!(type_var_cycles_resolve_as_possible); |
380 | // recursive type | 420 | // recursive type |
381 | return tv.fallback_value(); | 421 | return self.type_variable_table.fallback_value(tv, kind); |
382 | } | 422 | } |
383 | if let Some(known_ty) = | 423 | if let Some(known_ty) = |
384 | self.var_unification_table.inlined_probe_value(inner).known() | 424 | self.var_unification_table.inlined_probe_value(inner).known() |
@@ -400,12 +440,12 @@ impl InferenceTable { | |||
400 | /// replaced by Ty::Unknown. | 440 | /// replaced by Ty::Unknown. |
401 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 441 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
402 | ty.fold(&mut |ty| match ty { | 442 | ty.fold(&mut |ty| match ty { |
403 | Ty::Infer(tv) => { | 443 | Ty::InferenceVar(tv, kind) => { |
404 | let inner = tv.to_inner(); | 444 | let inner = tv.to_inner(); |
405 | if tv_stack.contains(&inner) { | 445 | if tv_stack.contains(&inner) { |
406 | mark::hit!(type_var_cycles_resolve_completely); | 446 | mark::hit!(type_var_cycles_resolve_completely); |
407 | // recursive type | 447 | // recursive type |
408 | return tv.fallback_value(); | 448 | return self.type_variable_table.fallback_value(tv, kind); |
409 | } | 449 | } |
410 | if let Some(known_ty) = | 450 | if let Some(known_ty) = |
411 | self.var_unification_table.inlined_probe_value(inner).known() | 451 | self.var_unification_table.inlined_probe_value(inner).known() |
@@ -416,7 +456,7 @@ impl InferenceTable { | |||
416 | tv_stack.pop(); | 456 | tv_stack.pop(); |
417 | result | 457 | result |
418 | } else { | 458 | } else { |
419 | tv.fallback_value() | 459 | self.type_variable_table.fallback_value(tv, kind) |
420 | } | 460 | } |
421 | } | 461 | } |
422 | _ => ty, | 462 | _ => ty, |
@@ -426,7 +466,7 @@ impl InferenceTable { | |||
426 | 466 | ||
427 | /// The ID of a type variable. | 467 | /// The ID of a type variable. |
428 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | 468 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
429 | pub struct TypeVarId(pub(super) u32); | 469 | pub(super) struct TypeVarId(pub(super) u32); |
430 | 470 | ||
431 | impl UnifyKey for TypeVarId { | 471 | impl UnifyKey for TypeVarId { |
432 | type Value = TypeVarValue; | 472 | type Value = TypeVarValue; |
@@ -447,7 +487,7 @@ impl UnifyKey for TypeVarId { | |||
447 | /// The value of a type variable: either we already know the type, or we don't | 487 | /// The value of a type variable: either we already know the type, or we don't |
448 | /// know it yet. | 488 | /// know it yet. |
449 | #[derive(Clone, PartialEq, Eq, Debug)] | 489 | #[derive(Clone, PartialEq, Eq, Debug)] |
450 | pub enum TypeVarValue { | 490 | pub(super) enum TypeVarValue { |
451 | Known(Ty), | 491 | Known(Ty), |
452 | Unknown, | 492 | Unknown, |
453 | } | 493 | } |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 50d248674..9bcaf6fa7 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, |
@@ -38,19 +38,18 @@ use itertools::Itertools; | |||
38 | use crate::{ | 38 | use crate::{ |
39 | db::HirDatabase, | 39 | db::HirDatabase, |
40 | display::HirDisplay, | 40 | display::HirDisplay, |
41 | primitive::{FloatTy, IntTy}, | ||
42 | utils::{generics, make_mut_slice, Generics}, | 41 | utils::{generics, make_mut_slice, Generics}, |
43 | }; | 42 | }; |
44 | 43 | ||
45 | pub use autoderef::autoderef; | 44 | pub use autoderef::autoderef; |
46 | pub use infer::{InferTy, InferenceResult}; | 45 | pub use infer::{InferenceResult, InferenceVar}; |
47 | pub use lower::{ | 46 | pub use lower::{ |
48 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 47 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
49 | TyDefId, TyLoweringContext, ValueTyDefId, | 48 | TyDefId, TyLoweringContext, ValueTyDefId, |
50 | }; | 49 | }; |
51 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 50 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
52 | 51 | ||
53 | pub use chalk_ir::{BoundVar, DebruijnIndex}; | 52 | pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar, TyVariableKind}; |
54 | 53 | ||
55 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
56 | pub enum Lifetime { | 55 | pub enum Lifetime { |
@@ -58,211 +57,6 @@ pub enum Lifetime { | |||
58 | Static, | 57 | Static, |
59 | } | 58 | } |
60 | 59 | ||
61 | /// A type constructor or type name: this might be something like the primitive | ||
62 | /// type `bool`, a struct like `Vec`, or things like function pointers or | ||
63 | /// tuples. | ||
64 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | ||
65 | pub enum TypeCtor { | ||
66 | /// The primitive boolean type. Written as `bool`. | ||
67 | Bool, | ||
68 | |||
69 | /// The primitive character type; holds a Unicode scalar value | ||
70 | /// (a non-surrogate code point). Written as `char`. | ||
71 | Char, | ||
72 | |||
73 | /// A primitive integer type. For example, `i32`. | ||
74 | Int(IntTy), | ||
75 | |||
76 | /// A primitive floating-point type. For example, `f64`. | ||
77 | Float(FloatTy), | ||
78 | |||
79 | /// Structures, enumerations and unions. | ||
80 | Adt(AdtId), | ||
81 | |||
82 | /// The pointee of a string slice. Written as `str`. | ||
83 | Str, | ||
84 | |||
85 | /// The pointee of an array slice. Written as `[T]`. | ||
86 | Slice, | ||
87 | |||
88 | /// An array with the given length. Written as `[T; n]`. | ||
89 | Array, | ||
90 | |||
91 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
92 | RawPtr(Mutability), | ||
93 | |||
94 | /// A reference; a pointer with an associated lifetime. Written as | ||
95 | /// `&'a mut T` or `&'a T`. | ||
96 | Ref(Mutability), | ||
97 | |||
98 | /// The anonymous type of a function declaration/definition. Each | ||
99 | /// function has a unique type, which is output (for a function | ||
100 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
101 | /// | ||
102 | /// This includes tuple struct / enum variant constructors as well. | ||
103 | /// | ||
104 | /// For example the type of `bar` here: | ||
105 | /// | ||
106 | /// ``` | ||
107 | /// fn foo() -> i32 { 1 } | ||
108 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
109 | /// ``` | ||
110 | FnDef(CallableDefId), | ||
111 | |||
112 | /// A pointer to a function. Written as `fn() -> i32`. | ||
113 | /// | ||
114 | /// For example the type of `bar` here: | ||
115 | /// | ||
116 | /// ``` | ||
117 | /// fn foo() -> i32 { 1 } | ||
118 | /// let bar: fn() -> i32 = foo; | ||
119 | /// ``` | ||
120 | // FIXME make this a Ty variant like in Chalk | ||
121 | FnPtr { num_args: u16, is_varargs: bool }, | ||
122 | |||
123 | /// The never type `!`. | ||
124 | Never, | ||
125 | |||
126 | /// A tuple type. For example, `(i32, bool)`. | ||
127 | Tuple { cardinality: u16 }, | ||
128 | |||
129 | /// Represents an associated item like `Iterator::Item`. This is used | ||
130 | /// when we have tried to normalize a projection like `T::Item` but | ||
131 | /// couldn't find a better representation. In that case, we generate | ||
132 | /// an **application type** like `(Iterator::Item)<T>`. | ||
133 | AssociatedType(TypeAliasId), | ||
134 | |||
135 | /// This represents a placeholder for an opaque type in situations where we | ||
136 | /// don't know the hidden type (i.e. currently almost always). This is | ||
137 | /// analogous to the `AssociatedType` type constructor. | ||
138 | /// It is also used as the type of async block, with one type parameter | ||
139 | /// representing the Future::Output type. | ||
140 | OpaqueType(OpaqueTyId), | ||
141 | |||
142 | /// Represents a foreign type declared in external blocks. | ||
143 | ForeignType(TypeAliasId), | ||
144 | |||
145 | /// The type of a specific closure. | ||
146 | /// | ||
147 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
148 | /// parameter. | ||
149 | Closure { def: DefWithBodyId, expr: ExprId }, | ||
150 | } | ||
151 | |||
152 | impl TypeCtor { | ||
153 | pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { | ||
154 | match self { | ||
155 | TypeCtor::Bool | ||
156 | | TypeCtor::Char | ||
157 | | TypeCtor::Int(_) | ||
158 | | TypeCtor::Float(_) | ||
159 | | TypeCtor::Str | ||
160 | | TypeCtor::Never => 0, | ||
161 | TypeCtor::Slice | ||
162 | | TypeCtor::Array | ||
163 | | TypeCtor::RawPtr(_) | ||
164 | | TypeCtor::Ref(_) | ||
165 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | ||
166 | => 1, | ||
167 | TypeCtor::Adt(adt) => { | ||
168 | let generic_params = generics(db.upcast(), adt.into()); | ||
169 | generic_params.len() | ||
170 | } | ||
171 | TypeCtor::FnDef(callable) => { | ||
172 | let generic_params = generics(db.upcast(), callable.into()); | ||
173 | generic_params.len() | ||
174 | } | ||
175 | TypeCtor::AssociatedType(type_alias) => { | ||
176 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
177 | generic_params.len() | ||
178 | } | ||
179 | TypeCtor::ForeignType(type_alias) => { | ||
180 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
181 | generic_params.len() | ||
182 | } | ||
183 | TypeCtor::OpaqueType(opaque_ty_id) => { | ||
184 | match opaque_ty_id { | ||
185 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
186 | let generic_params = generics(db.upcast(), func.into()); | ||
187 | generic_params.len() | ||
188 | } | ||
189 | // 1 param representing Future::Output type. | ||
190 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
191 | } | ||
192 | } | ||
193 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | ||
194 | TypeCtor::Tuple { cardinality } => cardinality as usize, | ||
195 | } | ||
196 | } | ||
197 | |||
198 | pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> { | ||
199 | match self { | ||
200 | TypeCtor::Bool | ||
201 | | TypeCtor::Char | ||
202 | | TypeCtor::Int(_) | ||
203 | | TypeCtor::Float(_) | ||
204 | | TypeCtor::Str | ||
205 | | TypeCtor::Never | ||
206 | | TypeCtor::Slice | ||
207 | | TypeCtor::Array | ||
208 | | TypeCtor::RawPtr(_) | ||
209 | | TypeCtor::Ref(_) | ||
210 | | TypeCtor::FnPtr { .. } | ||
211 | | TypeCtor::Tuple { .. } => None, | ||
212 | // Closure's krate is irrelevant for coherence I would think? | ||
213 | TypeCtor::Closure { .. } => None, | ||
214 | TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()), | ||
215 | TypeCtor::FnDef(callable) => Some(callable.krate(db)), | ||
216 | TypeCtor::AssociatedType(type_alias) => { | ||
217 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
218 | } | ||
219 | TypeCtor::ForeignType(type_alias) => { | ||
220 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
221 | } | ||
222 | TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { | ||
223 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
224 | Some(func.lookup(db.upcast()).module(db.upcast()).krate()) | ||
225 | } | ||
226 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => { | ||
227 | Some(def.module(db.upcast()).krate()) | ||
228 | } | ||
229 | }, | ||
230 | } | ||
231 | } | ||
232 | |||
233 | pub fn as_generic_def(self) -> Option<GenericDefId> { | ||
234 | match self { | ||
235 | TypeCtor::Bool | ||
236 | | TypeCtor::Char | ||
237 | | TypeCtor::Int(_) | ||
238 | | TypeCtor::Float(_) | ||
239 | | TypeCtor::Str | ||
240 | | TypeCtor::Never | ||
241 | | TypeCtor::Slice | ||
242 | | TypeCtor::Array | ||
243 | | TypeCtor::RawPtr(_) | ||
244 | | TypeCtor::Ref(_) | ||
245 | | TypeCtor::FnPtr { .. } | ||
246 | | TypeCtor::Tuple { .. } | ||
247 | | TypeCtor::Closure { .. } => None, | ||
248 | TypeCtor::Adt(adt) => Some(adt.into()), | ||
249 | TypeCtor::FnDef(callable) => Some(callable.into()), | ||
250 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | ||
251 | TypeCtor::ForeignType(type_alias) => Some(type_alias.into()), | ||
252 | TypeCtor::OpaqueType(_impl_trait_id) => None, | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | |||
257 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
258 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
259 | /// several other things. | ||
260 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
261 | pub struct ApplicationTy { | ||
262 | pub ctor: TypeCtor, | ||
263 | pub parameters: Substs, | ||
264 | } | ||
265 | |||
266 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
267 | pub struct OpaqueTy { | 61 | pub struct OpaqueTy { |
268 | pub opaque_ty_id: OpaqueTyId, | 62 | pub opaque_ty_id: OpaqueTyId, |
@@ -305,29 +99,118 @@ impl TypeWalk for ProjectionTy { | |||
305 | } | 99 | } |
306 | } | 100 | } |
307 | 101 | ||
308 | /// A type. | 102 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
309 | /// | 103 | pub struct FnSig { |
310 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 104 | pub variadic: bool, |
311 | /// the same thing (but in a different way). | 105 | } |
312 | /// | 106 | |
313 | /// This should be cheap to clone. | ||
314 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 107 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
315 | pub enum Ty { | 108 | pub struct FnPointer { |
316 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | 109 | pub num_args: usize, |
317 | /// type like `bool`, a struct, tuple, function pointer, reference or | 110 | pub sig: FnSig, |
318 | /// several other things. | 111 | pub substs: Substs, |
319 | Apply(ApplicationTy), | 112 | } |
320 | 113 | ||
114 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
115 | pub enum AliasTy { | ||
321 | /// A "projection" type corresponds to an (unnormalized) | 116 | /// A "projection" type corresponds to an (unnormalized) |
322 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 117 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
323 | /// trait and all its parameters are fully known. | 118 | /// trait and all its parameters are fully known. |
324 | Projection(ProjectionTy), | 119 | Projection(ProjectionTy), |
325 | |||
326 | /// An opaque type (`impl Trait`). | 120 | /// An opaque type (`impl Trait`). |
327 | /// | 121 | /// |
328 | /// This is currently only used for return type impl trait; each instance of | 122 | /// This is currently only used for return type impl trait; each instance of |
329 | /// `impl Trait` in a return type gets its own ID. | 123 | /// `impl Trait` in a return type gets its own ID. |
330 | Opaque(OpaqueTy), | 124 | Opaque(OpaqueTy), |
125 | } | ||
126 | |||
127 | /// A type. | ||
128 | /// | ||
129 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | ||
130 | /// the same thing (but in a different way). | ||
131 | /// | ||
132 | /// This should be cheap to clone. | ||
133 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
134 | pub enum Ty { | ||
135 | /// Structures, enumerations and unions. | ||
136 | Adt(AdtId, Substs), | ||
137 | |||
138 | /// Represents an associated item like `Iterator::Item`. This is used | ||
139 | /// when we have tried to normalize a projection like `T::Item` but | ||
140 | /// couldn't find a better representation. In that case, we generate | ||
141 | /// an **application type** like `(Iterator::Item)<T>`. | ||
142 | AssociatedType(TypeAliasId, Substs), | ||
143 | |||
144 | /// a scalar type like `bool` or `u32` | ||
145 | Scalar(Scalar), | ||
146 | |||
147 | /// A tuple type. For example, `(i32, bool)`. | ||
148 | Tuple(usize, Substs), | ||
149 | |||
150 | /// An array with the given length. Written as `[T; n]`. | ||
151 | Array(Substs), | ||
152 | |||
153 | /// The pointee of an array slice. Written as `[T]`. | ||
154 | Slice(Substs), | ||
155 | |||
156 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
157 | Raw(Mutability, Substs), | ||
158 | |||
159 | /// A reference; a pointer with an associated lifetime. Written as | ||
160 | /// `&'a mut T` or `&'a T`. | ||
161 | Ref(Mutability, Substs), | ||
162 | |||
163 | /// This represents a placeholder for an opaque type in situations where we | ||
164 | /// don't know the hidden type (i.e. currently almost always). This is | ||
165 | /// analogous to the `AssociatedType` type constructor. | ||
166 | /// It is also used as the type of async block, with one type parameter | ||
167 | /// representing the Future::Output type. | ||
168 | OpaqueType(OpaqueTyId, Substs), | ||
169 | |||
170 | /// The anonymous type of a function declaration/definition. Each | ||
171 | /// function has a unique type, which is output (for a function | ||
172 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
173 | /// | ||
174 | /// This includes tuple struct / enum variant constructors as well. | ||
175 | /// | ||
176 | /// For example the type of `bar` here: | ||
177 | /// | ||
178 | /// ``` | ||
179 | /// fn foo() -> i32 { 1 } | ||
180 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
181 | /// ``` | ||
182 | FnDef(CallableDefId, Substs), | ||
183 | |||
184 | /// The pointee of a string slice. Written as `str`. | ||
185 | Str, | ||
186 | |||
187 | /// The never type `!`. | ||
188 | Never, | ||
189 | |||
190 | /// The type of a specific closure. | ||
191 | /// | ||
192 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
193 | /// parameter. | ||
194 | Closure(DefWithBodyId, ExprId, Substs), | ||
195 | |||
196 | /// Represents a foreign type declared in external blocks. | ||
197 | ForeignType(TypeAliasId), | ||
198 | |||
199 | /// A pointer to a function. Written as `fn() -> i32`. | ||
200 | /// | ||
201 | /// For example the type of `bar` here: | ||
202 | /// | ||
203 | /// ``` | ||
204 | /// fn foo() -> i32 { 1 } | ||
205 | /// let bar: fn() -> i32 = foo; | ||
206 | /// ``` | ||
207 | Function(FnPointer), | ||
208 | |||
209 | /// An "alias" type represents some form of type alias, such as: | ||
210 | /// - An associated type projection like `<T as Iterator>::Item` | ||
211 | /// - `impl Trait` types | ||
212 | /// - Named type aliases like `type Foo<X> = Vec<X>` | ||
213 | Alias(AliasTy), | ||
331 | 214 | ||
332 | /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) | 215 | /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) |
333 | /// {}` when we're type-checking the body of that function. In this | 216 | /// {}` when we're type-checking the body of that function. In this |
@@ -340,10 +223,10 @@ pub enum Ty { | |||
340 | /// parameters get turned into variables; during trait resolution, inference | 223 | /// parameters get turned into variables; during trait resolution, inference |
341 | /// variables get turned into bound variables and back; and in `Dyn` the | 224 | /// variables get turned into bound variables and back; and in `Dyn` the |
342 | /// `Self` type is represented with a bound variable as well. | 225 | /// `Self` type is represented with a bound variable as well. |
343 | Bound(BoundVar), | 226 | BoundVar(BoundVar), |
344 | 227 | ||
345 | /// A type variable used during type checking. | 228 | /// A type variable used during type checking. |
346 | Infer(InferTy), | 229 | InferenceVar(InferenceVar, TyVariableKind), |
347 | 230 | ||
348 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). | 231 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). |
349 | /// | 232 | /// |
@@ -424,7 +307,7 @@ impl Substs { | |||
424 | generic_params | 307 | generic_params |
425 | .iter() | 308 | .iter() |
426 | .enumerate() | 309 | .enumerate() |
427 | .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) | 310 | .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) |
428 | .collect(), | 311 | .collect(), |
429 | ) | 312 | ) |
430 | } | 313 | } |
@@ -440,10 +323,6 @@ impl Substs { | |||
440 | Substs::builder(generic_params.len()) | 323 | Substs::builder(generic_params.len()) |
441 | } | 324 | } |
442 | 325 | ||
443 | pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { | ||
444 | Substs::builder(type_ctor.num_ty_params(db)) | ||
445 | } | ||
446 | |||
447 | fn builder(param_count: usize) -> SubstsBuilder { | 326 | fn builder(param_count: usize) -> SubstsBuilder { |
448 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | 327 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } |
449 | } | 328 | } |
@@ -476,7 +355,7 @@ impl SubstsBuilder { | |||
476 | } | 355 | } |
477 | 356 | ||
478 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { | 357 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { |
479 | self.fill((starting_from..).map(|idx| Ty::Bound(BoundVar::new(debruijn, idx)))) | 358 | self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx)))) |
480 | } | 359 | } |
481 | 360 | ||
482 | pub fn fill_with_unknown(self) -> Self { | 361 | pub fn fill_with_unknown(self) -> Self { |
@@ -656,41 +535,41 @@ impl TypeWalk for GenericPredicate { | |||
656 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 535 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
657 | pub struct Canonical<T> { | 536 | pub struct Canonical<T> { |
658 | pub value: T, | 537 | pub value: T, |
659 | pub kinds: Arc<[TyKind]>, | 538 | pub kinds: Arc<[TyVariableKind]>, |
660 | } | 539 | } |
661 | 540 | ||
662 | impl<T> Canonical<T> { | 541 | impl<T> Canonical<T> { |
663 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { | 542 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { |
664 | Self { value, kinds: kinds.into_iter().collect() } | 543 | Self { value, kinds: kinds.into_iter().collect() } |
665 | } | 544 | } |
666 | } | 545 | } |
667 | 546 | ||
668 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
669 | pub enum TyKind { | ||
670 | General, | ||
671 | Integer, | ||
672 | Float, | ||
673 | } | ||
674 | |||
675 | /// A function signature as seen by type inference: Several parameter types and | 547 | /// A function signature as seen by type inference: Several parameter types and |
676 | /// one return type. | 548 | /// one return type. |
677 | #[derive(Clone, PartialEq, Eq, Debug)] | 549 | #[derive(Clone, PartialEq, Eq, Debug)] |
678 | pub struct FnSig { | 550 | pub struct CallableSig { |
679 | params_and_return: Arc<[Ty]>, | 551 | params_and_return: Arc<[Ty]>, |
680 | is_varargs: bool, | 552 | is_varargs: bool, |
681 | } | 553 | } |
682 | 554 | ||
683 | /// A polymorphic function signature. | 555 | /// A polymorphic function signature. |
684 | pub type PolyFnSig = Binders<FnSig>; | 556 | pub type PolyFnSig = Binders<CallableSig>; |
685 | 557 | ||
686 | impl FnSig { | 558 | impl CallableSig { |
687 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { | 559 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig { |
688 | params.push(ret); | 560 | params.push(ret); |
689 | FnSig { params_and_return: params.into(), is_varargs } | 561 | CallableSig { params_and_return: params.into(), is_varargs } |
690 | } | 562 | } |
691 | 563 | ||
692 | pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { | 564 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { |
693 | FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } | 565 | CallableSig { |
566 | params_and_return: Arc::clone(&fn_ptr.substs.0), | ||
567 | is_varargs: fn_ptr.sig.variadic, | ||
568 | } | ||
569 | } | ||
570 | |||
571 | pub fn from_substs(substs: &Substs) -> CallableSig { | ||
572 | CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } | ||
694 | } | 573 | } |
695 | 574 | ||
696 | pub fn params(&self) -> &[Ty] { | 575 | pub fn params(&self) -> &[Ty] { |
@@ -702,7 +581,7 @@ impl FnSig { | |||
702 | } | 581 | } |
703 | } | 582 | } |
704 | 583 | ||
705 | impl TypeWalk for FnSig { | 584 | impl TypeWalk for CallableSig { |
706 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 585 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
707 | for t in self.params_and_return.iter() { | 586 | for t in self.params_and_return.iter() { |
708 | t.walk(f); | 587 | t.walk(f); |
@@ -721,49 +600,42 @@ impl TypeWalk for FnSig { | |||
721 | } | 600 | } |
722 | 601 | ||
723 | impl Ty { | 602 | impl Ty { |
724 | pub fn simple(ctor: TypeCtor) -> Ty { | ||
725 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) | ||
726 | } | ||
727 | pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { | ||
728 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) | ||
729 | } | ||
730 | pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { | ||
731 | Ty::Apply(ApplicationTy { ctor, parameters }) | ||
732 | } | ||
733 | pub fn unit() -> Self { | 603 | pub fn unit() -> Self { |
734 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 604 | Ty::Tuple(0, Substs::empty()) |
735 | } | 605 | } |
736 | pub fn fn_ptr(sig: FnSig) -> Self { | 606 | |
737 | Ty::apply( | 607 | pub fn fn_ptr(sig: CallableSig) -> Self { |
738 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, | 608 | Ty::Function(FnPointer { |
739 | Substs(sig.params_and_return), | 609 | num_args: sig.params().len(), |
740 | ) | 610 | sig: FnSig { variadic: sig.is_varargs }, |
611 | substs: Substs(sig.params_and_return), | ||
612 | }) | ||
741 | } | 613 | } |
614 | |||
742 | pub fn builtin(builtin: BuiltinType) -> Self { | 615 | pub fn builtin(builtin: BuiltinType) -> Self { |
743 | Ty::simple(match builtin { | 616 | match builtin { |
744 | BuiltinType::Char => TypeCtor::Char, | 617 | BuiltinType::Char => Ty::Scalar(Scalar::Char), |
745 | BuiltinType::Bool => TypeCtor::Bool, | 618 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), |
746 | BuiltinType::Str => TypeCtor::Str, | 619 | BuiltinType::Str => Ty::Str, |
747 | BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), | 620 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), |
748 | BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), | 621 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), |
749 | }) | 622 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), |
623 | } | ||
750 | } | 624 | } |
751 | 625 | ||
752 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 626 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
753 | match self { | 627 | match self { |
754 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 628 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), |
755 | Some((parameters.as_single(), *mutability)) | ||
756 | } | ||
757 | _ => None, | 629 | _ => None, |
758 | } | 630 | } |
759 | } | 631 | } |
760 | 632 | ||
761 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 633 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
762 | match self { | 634 | match self { |
763 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 635 | Ty::Ref(mutability, parameters) => { |
764 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 636 | Some((parameters.as_single(), Rawness::Ref, *mutability)) |
765 | } | 637 | } |
766 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | 638 | Ty::Raw(mutability, parameters) => { |
767 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | 639 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) |
768 | } | 640 | } |
769 | _ => None, | 641 | _ => None, |
@@ -773,7 +645,7 @@ impl Ty { | |||
773 | pub fn strip_references(&self) -> &Ty { | 645 | pub fn strip_references(&self) -> &Ty { |
774 | let mut t: &Ty = self; | 646 | let mut t: &Ty = self; |
775 | 647 | ||
776 | while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { | 648 | while let Ty::Ref(_mutability, parameters) = t { |
777 | t = parameters.as_single(); | 649 | t = parameters.as_single(); |
778 | } | 650 | } |
779 | 651 | ||
@@ -782,30 +654,60 @@ impl Ty { | |||
782 | 654 | ||
783 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { | 655 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { |
784 | match self { | 656 | match self { |
785 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 657 | Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)), |
786 | Some((*adt_def, parameters)) | ||
787 | } | ||
788 | _ => None, | 658 | _ => None, |
789 | } | 659 | } |
790 | } | 660 | } |
791 | 661 | ||
792 | pub fn as_tuple(&self) -> Option<&Substs> { | 662 | pub fn as_tuple(&self) -> Option<&Substs> { |
793 | match self { | 663 | match self { |
794 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | 664 | Ty::Tuple(_, substs) => Some(substs), |
795 | Some(parameters) | 665 | _ => None, |
796 | } | 666 | } |
667 | } | ||
668 | |||
669 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | ||
670 | match *self { | ||
671 | Ty::Adt(adt, ..) => Some(adt.into()), | ||
672 | Ty::FnDef(callable, ..) => Some(callable.into()), | ||
673 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | ||
674 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | ||
797 | _ => None, | 675 | _ => None, |
798 | } | 676 | } |
799 | } | 677 | } |
800 | 678 | ||
801 | pub fn is_never(&self) -> bool { | 679 | pub fn is_never(&self) -> bool { |
802 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 680 | matches!(self, Ty::Never) |
803 | } | 681 | } |
804 | 682 | ||
805 | pub fn is_unknown(&self) -> bool { | 683 | pub fn is_unknown(&self) -> bool { |
806 | matches!(self, Ty::Unknown) | 684 | matches!(self, Ty::Unknown) |
807 | } | 685 | } |
808 | 686 | ||
687 | pub fn equals_ctor(&self, other: &Ty) -> bool { | ||
688 | match (self, other) { | ||
689 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | ||
690 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | ||
691 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | ||
692 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | ||
693 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | ||
694 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | ||
695 | (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { | ||
696 | expr == expr2 && def == def2 | ||
697 | } | ||
698 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
699 | | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2, | ||
700 | ( | ||
701 | Ty::Function(FnPointer { num_args, sig, .. }), | ||
702 | Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), | ||
703 | ) => num_args == num_args2 && sig == sig2, | ||
704 | (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, | ||
705 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | ||
706 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | ||
707 | _ => false, | ||
708 | } | ||
709 | } | ||
710 | |||
809 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 711 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
810 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 712 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
811 | match self { | 713 | match self { |
@@ -824,41 +726,30 @@ impl Ty { | |||
824 | 726 | ||
825 | fn builtin_deref(&self) -> Option<Ty> { | 727 | fn builtin_deref(&self) -> Option<Ty> { |
826 | match self { | 728 | match self { |
827 | Ty::Apply(a_ty) => match a_ty.ctor { | 729 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), |
828 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 730 | Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), |
829 | TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), | ||
830 | _ => None, | ||
831 | }, | ||
832 | _ => None, | 731 | _ => None, |
833 | } | 732 | } |
834 | } | 733 | } |
835 | 734 | ||
836 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 735 | pub fn as_fn_def(&self) -> Option<FunctionId> { |
837 | match self { | 736 | match self { |
838 | &Ty::Apply(ApplicationTy { | 737 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), |
839 | ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), | ||
840 | .. | ||
841 | }) => Some(func), | ||
842 | _ => None, | 738 | _ => None, |
843 | } | 739 | } |
844 | } | 740 | } |
845 | 741 | ||
846 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 742 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { |
847 | match self { | 743 | match self { |
848 | Ty::Apply(a_ty) => match a_ty.ctor { | 744 | Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), |
849 | TypeCtor::FnPtr { is_varargs, .. } => { | 745 | Ty::FnDef(def, parameters) => { |
850 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | 746 | let sig = db.callable_item_signature(*def); |
851 | } | 747 | Some(sig.subst(¶meters)) |
852 | TypeCtor::FnDef(def) => { | 748 | } |
853 | let sig = db.callable_item_signature(def); | 749 | Ty::Closure(.., substs) => { |
854 | Some(sig.subst(&a_ty.parameters)) | 750 | let sig_param = &substs[0]; |
855 | } | 751 | sig_param.callable_sig(db) |
856 | TypeCtor::Closure { .. } => { | 752 | } |
857 | let sig_param = &a_ty.parameters[0]; | ||
858 | sig_param.callable_sig(db) | ||
859 | } | ||
860 | _ => None, | ||
861 | }, | ||
862 | _ => None, | 753 | _ => None, |
863 | } | 754 | } |
864 | } | 755 | } |
@@ -867,28 +758,66 @@ impl Ty { | |||
867 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | 758 | /// the `Substs` for these type parameters with the given ones. (So e.g. if |
868 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 759 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
869 | /// `Option<u32>` afterwards.) | 760 | /// `Option<u32>` afterwards.) |
870 | pub fn apply_substs(self, substs: Substs) -> Ty { | 761 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
871 | match self { | 762 | match &mut self { |
872 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | 763 | Ty::Adt(_, substs) |
873 | assert_eq!(previous_substs.len(), substs.len()); | 764 | | Ty::Slice(substs) |
874 | Ty::Apply(ApplicationTy { ctor, parameters: substs }) | 765 | | Ty::Array(substs) |
766 | | Ty::Raw(_, substs) | ||
767 | | Ty::Ref(_, substs) | ||
768 | | Ty::FnDef(_, substs) | ||
769 | | Ty::Function(FnPointer { substs, .. }) | ||
770 | | Ty::Tuple(_, substs) | ||
771 | | Ty::OpaqueType(_, substs) | ||
772 | | Ty::AssociatedType(_, substs) | ||
773 | | Ty::Closure(.., substs) => { | ||
774 | assert_eq!(substs.len(), new_substs.len()); | ||
775 | *substs = new_substs; | ||
875 | } | 776 | } |
876 | _ => self, | 777 | _ => (), |
877 | } | 778 | } |
779 | self | ||
878 | } | 780 | } |
879 | 781 | ||
880 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 782 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
881 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 783 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
882 | pub fn substs(&self) -> Option<Substs> { | 784 | pub fn substs(&self) -> Option<&Substs> { |
883 | match self { | 785 | match self { |
884 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | 786 | Ty::Adt(_, substs) |
787 | | Ty::Slice(substs) | ||
788 | | Ty::Array(substs) | ||
789 | | Ty::Raw(_, substs) | ||
790 | | Ty::Ref(_, substs) | ||
791 | | Ty::FnDef(_, substs) | ||
792 | | Ty::Function(FnPointer { substs, .. }) | ||
793 | | Ty::Tuple(_, substs) | ||
794 | | Ty::OpaqueType(_, substs) | ||
795 | | Ty::AssociatedType(_, substs) | ||
796 | | Ty::Closure(.., substs) => Some(substs), | ||
797 | _ => None, | ||
798 | } | ||
799 | } | ||
800 | |||
801 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | ||
802 | match self { | ||
803 | Ty::Adt(_, substs) | ||
804 | | Ty::Slice(substs) | ||
805 | | Ty::Array(substs) | ||
806 | | Ty::Raw(_, substs) | ||
807 | | Ty::Ref(_, substs) | ||
808 | | Ty::FnDef(_, substs) | ||
809 | | Ty::Function(FnPointer { substs, .. }) | ||
810 | | Ty::Tuple(_, substs) | ||
811 | | Ty::OpaqueType(_, substs) | ||
812 | | Ty::AssociatedType(_, substs) | ||
813 | | Ty::Closure(.., substs) => Some(substs), | ||
885 | _ => None, | 814 | _ => None, |
886 | } | 815 | } |
887 | } | 816 | } |
888 | 817 | ||
889 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 818 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
890 | match self { | 819 | match self { |
891 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | 820 | Ty::OpaqueType(opaque_ty_id, ..) => { |
892 | match opaque_ty_id { | 821 | match opaque_ty_id { |
893 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 822 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { |
894 | let krate = def.module(db.upcast()).krate(); | 823 | let krate = def.module(db.upcast()).krate(); |
@@ -911,7 +840,7 @@ impl Ty { | |||
911 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | 840 | OpaqueTyId::ReturnTypeImplTrait(..) => None, |
912 | } | 841 | } |
913 | } | 842 | } |
914 | Ty::Opaque(opaque_ty) => { | 843 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { |
915 | let predicates = match opaque_ty.opaque_ty_id { | 844 | let predicates = match opaque_ty.opaque_ty_id { |
916 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 845 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
917 | db.return_type_impl_traits(func).map(|it| { | 846 | db.return_type_impl_traits(func).map(|it| { |
@@ -949,13 +878,13 @@ impl Ty { | |||
949 | 878 | ||
950 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 879 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
951 | match self { | 880 | match self { |
952 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | 881 | Ty::AssociatedType(type_alias_id, ..) => { |
953 | match type_alias_id.lookup(db.upcast()).container { | 882 | match type_alias_id.lookup(db.upcast()).container { |
954 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 883 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
955 | _ => None, | 884 | _ => None, |
956 | } | 885 | } |
957 | } | 886 | } |
958 | Ty::Projection(projection_ty) => { | 887 | Ty::Alias(AliasTy::Projection(projection_ty)) => { |
959 | match projection_ty.associated_ty.lookup(db.upcast()).container { | 888 | match projection_ty.associated_ty.lookup(db.upcast()).container { |
960 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 889 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
961 | _ => None, | 890 | _ => None, |
@@ -1033,7 +962,7 @@ pub trait TypeWalk { | |||
1033 | { | 962 | { |
1034 | self.walk_mut_binders( | 963 | self.walk_mut_binders( |
1035 | &mut |ty, binders| { | 964 | &mut |ty, binders| { |
1036 | if let &mut Ty::Bound(bound) = ty { | 965 | if let &mut Ty::BoundVar(bound) = ty { |
1037 | if bound.debruijn >= binders { | 966 | if bound.debruijn >= binders { |
1038 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 967 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
1039 | } | 968 | } |
@@ -1051,8 +980,8 @@ pub trait TypeWalk { | |||
1051 | { | 980 | { |
1052 | self.fold_binders( | 981 | self.fold_binders( |
1053 | &mut |ty, binders| match ty { | 982 | &mut |ty, binders| match ty { |
1054 | Ty::Bound(bound) if bound.debruijn >= binders => { | 983 | Ty::BoundVar(bound) if bound.debruijn >= binders => { |
1055 | Ty::Bound(bound.shifted_in_from(n)) | 984 | Ty::BoundVar(bound.shifted_in_from(n)) |
1056 | } | 985 | } |
1057 | ty => ty, | 986 | ty => ty, |
1058 | }, | 987 | }, |
@@ -1064,13 +993,13 @@ pub trait TypeWalk { | |||
1064 | impl TypeWalk for Ty { | 993 | impl TypeWalk for Ty { |
1065 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 994 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
1066 | match self { | 995 | match self { |
1067 | Ty::Apply(a_ty) => { | 996 | Ty::Alias(AliasTy::Projection(p_ty)) => { |
1068 | for t in a_ty.parameters.iter() { | 997 | for t in p_ty.parameters.iter() { |
1069 | t.walk(f); | 998 | t.walk(f); |
1070 | } | 999 | } |
1071 | } | 1000 | } |
1072 | Ty::Projection(p_ty) => { | 1001 | Ty::Alias(AliasTy::Opaque(o_ty)) => { |
1073 | for t in p_ty.parameters.iter() { | 1002 | for t in o_ty.parameters.iter() { |
1074 | t.walk(f); | 1003 | t.walk(f); |
1075 | } | 1004 | } |
1076 | } | 1005 | } |
@@ -1079,12 +1008,13 @@ impl TypeWalk for Ty { | |||
1079 | p.walk(f); | 1008 | p.walk(f); |
1080 | } | 1009 | } |
1081 | } | 1010 | } |
1082 | Ty::Opaque(o_ty) => { | 1011 | _ => { |
1083 | for t in o_ty.parameters.iter() { | 1012 | if let Some(substs) = self.substs() { |
1084 | t.walk(f); | 1013 | for t in substs.iter() { |
1014 | t.walk(f); | ||
1015 | } | ||
1085 | } | 1016 | } |
1086 | } | 1017 | } |
1087 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
1088 | } | 1018 | } |
1089 | f(self); | 1019 | f(self); |
1090 | } | 1020 | } |
@@ -1095,10 +1025,7 @@ impl TypeWalk for Ty { | |||
1095 | binders: DebruijnIndex, | 1025 | binders: DebruijnIndex, |
1096 | ) { | 1026 | ) { |
1097 | match self { | 1027 | match self { |
1098 | Ty::Apply(a_ty) => { | 1028 | Ty::Alias(AliasTy::Projection(p_ty)) => { |
1099 | a_ty.parameters.walk_mut_binders(f, binders); | ||
1100 | } | ||
1101 | Ty::Projection(p_ty) => { | ||
1102 | p_ty.parameters.walk_mut_binders(f, binders); | 1029 | p_ty.parameters.walk_mut_binders(f, binders); |
1103 | } | 1030 | } |
1104 | Ty::Dyn(predicates) => { | 1031 | Ty::Dyn(predicates) => { |
@@ -1106,10 +1033,14 @@ impl TypeWalk for Ty { | |||
1106 | p.walk_mut_binders(f, binders.shifted_in()); | 1033 | p.walk_mut_binders(f, binders.shifted_in()); |
1107 | } | 1034 | } |
1108 | } | 1035 | } |
1109 | Ty::Opaque(o_ty) => { | 1036 | Ty::Alias(AliasTy::Opaque(o_ty)) => { |
1110 | o_ty.parameters.walk_mut_binders(f, binders); | 1037 | o_ty.parameters.walk_mut_binders(f, binders); |
1111 | } | 1038 | } |
1112 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1039 | _ => { |
1040 | if let Some(substs) = self.substs_mut() { | ||
1041 | substs.walk_mut_binders(f, binders); | ||
1042 | } | ||
1043 | } | ||
1113 | } | 1044 | } |
1114 | f(self, binders); | 1045 | f(self, binders); |
1115 | } | 1046 | } |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 99b0ecf3b..ca06c9fe2 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -31,9 +31,9 @@ use crate::{ | |||
31 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 31 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
32 | make_mut_slice, variant_data, | 32 | make_mut_slice, variant_data, |
33 | }, | 33 | }, |
34 | Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, | 34 | AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, |
35 | ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, | 35 | OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, |
36 | TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 36 | ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #[derive(Debug)] | 39 | #[derive(Debug)] |
@@ -145,13 +145,10 @@ impl Ty { | |||
145 | pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { | 145 | pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { |
146 | let mut res = None; | 146 | let mut res = None; |
147 | let ty = match type_ref { | 147 | let ty = match type_ref { |
148 | TypeRef::Never => Ty::simple(TypeCtor::Never), | 148 | TypeRef::Never => Ty::Never, |
149 | TypeRef::Tuple(inner) => { | 149 | TypeRef::Tuple(inner) => { |
150 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); | 150 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); |
151 | Ty::apply( | 151 | Ty::Tuple(inner_tys.len(), Substs(inner_tys)) |
152 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | ||
153 | Substs(inner_tys), | ||
154 | ) | ||
155 | } | 152 | } |
156 | TypeRef::Path(path) => { | 153 | TypeRef::Path(path) => { |
157 | let (ty, res_) = Ty::from_hir_path(ctx, path); | 154 | let (ty, res_) = Ty::from_hir_path(ctx, path); |
@@ -160,30 +157,31 @@ 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::Raw(*mutability, Substs::single(inner_ty)) |
164 | } | 161 | } |
165 | TypeRef::Array(inner) => { | 162 | TypeRef::Array(inner) => { |
166 | let inner_ty = Ty::from_hir(ctx, inner); | 163 | let inner_ty = Ty::from_hir(ctx, inner); |
167 | Ty::apply_one(TypeCtor::Array, inner_ty) | 164 | Ty::Array(Substs::single(inner_ty)) |
168 | } | 165 | } |
169 | TypeRef::Slice(inner) => { | 166 | TypeRef::Slice(inner) => { |
170 | let inner_ty = Ty::from_hir(ctx, inner); | 167 | let inner_ty = Ty::from_hir(ctx, inner); |
171 | Ty::apply_one(TypeCtor::Slice, inner_ty) | 168 | Ty::Slice(Substs::single(inner_ty)) |
172 | } | 169 | } |
173 | TypeRef::Reference(inner, _, mutability) => { | 170 | TypeRef::Reference(inner, _, mutability) => { |
174 | let inner_ty = Ty::from_hir(ctx, inner); | 171 | let inner_ty = Ty::from_hir(ctx, inner); |
175 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 172 | Ty::Ref(*mutability, Substs::single(inner_ty)) |
176 | } | 173 | } |
177 | TypeRef::Placeholder => Ty::Unknown, | 174 | TypeRef::Placeholder => Ty::Unknown, |
178 | TypeRef::Fn(params, is_varargs) => { | 175 | TypeRef::Fn(params, is_varargs) => { |
179 | let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); | 176 | let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); |
180 | Ty::apply( | 177 | Ty::Function(FnPointer { |
181 | TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs }, | 178 | num_args: substs.len() - 1, |
182 | sig, | 179 | sig: FnSig { variadic: *is_varargs }, |
183 | ) | 180 | substs, |
181 | }) | ||
184 | } | 182 | } |
185 | TypeRef::DynTrait(bounds) => { | 183 | TypeRef::DynTrait(bounds) => { |
186 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 184 | let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); |
187 | let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { | 185 | let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
188 | bounds | 186 | bounds |
189 | .iter() | 187 | .iter() |
@@ -227,7 +225,10 @@ impl Ty { | |||
227 | let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); | 225 | let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); |
228 | let generics = generics(ctx.db.upcast(), func.into()); | 226 | let generics = generics(ctx.db.upcast(), func.into()); |
229 | let parameters = Substs::bound_vars(&generics, ctx.in_binders); | 227 | let parameters = Substs::bound_vars(&generics, ctx.in_binders); |
230 | Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) | 228 | Ty::Alias(AliasTy::Opaque(OpaqueTy { |
229 | opaque_ty_id: impl_trait_id, | ||
230 | parameters, | ||
231 | })) | ||
231 | } | 232 | } |
232 | ImplTraitLoweringMode::Param => { | 233 | ImplTraitLoweringMode::Param => { |
233 | let idx = ctx.impl_trait_counter.get(); | 234 | let idx = ctx.impl_trait_counter.get(); |
@@ -258,7 +259,7 @@ impl Ty { | |||
258 | } else { | 259 | } else { |
259 | (0, 0, 0, 0) | 260 | (0, 0, 0, 0) |
260 | }; | 261 | }; |
261 | Ty::Bound(BoundVar::new( | 262 | Ty::BoundVar(BoundVar::new( |
262 | ctx.in_binders, | 263 | ctx.in_binders, |
263 | idx as usize + parent_params + self_params + list_params, | 264 | idx as usize + parent_params + self_params + list_params, |
264 | )) | 265 | )) |
@@ -330,7 +331,7 @@ impl Ty { | |||
330 | TypeNs::TraitId(trait_) => { | 331 | TypeNs::TraitId(trait_) => { |
331 | // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there | 332 | // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there |
332 | let self_ty = if remaining_segments.len() == 0 { | 333 | let self_ty = if remaining_segments.len() == 0 { |
333 | Some(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0))) | 334 | Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))) |
334 | } else { | 335 | } else { |
335 | None | 336 | None |
336 | }; | 337 | }; |
@@ -346,10 +347,10 @@ impl Ty { | |||
346 | match found { | 347 | match found { |
347 | Some((super_trait_ref, associated_ty)) => { | 348 | Some((super_trait_ref, associated_ty)) => { |
348 | // FIXME handle type parameters on the segment | 349 | // FIXME handle type parameters on the segment |
349 | Ty::Projection(ProjectionTy { | 350 | Ty::Alias(AliasTy::Projection(ProjectionTy { |
350 | associated_ty, | 351 | associated_ty, |
351 | parameters: super_trait_ref.substs, | 352 | parameters: super_trait_ref.substs, |
352 | }) | 353 | })) |
353 | } | 354 | } |
354 | None => { | 355 | None => { |
355 | // FIXME: report error (associated type not found) | 356 | // FIXME: report error (associated type not found) |
@@ -373,7 +374,7 @@ impl Ty { | |||
373 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), | 374 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), |
374 | TypeParamLoweringMode::Variable => { | 375 | TypeParamLoweringMode::Variable => { |
375 | let idx = generics.param_idx(param_id).expect("matching generics"); | 376 | let idx = generics.param_idx(param_id).expect("matching generics"); |
376 | Ty::Bound(BoundVar::new(ctx.in_binders, idx)) | 377 | Ty::BoundVar(BoundVar::new(ctx.in_binders, idx)) |
377 | } | 378 | } |
378 | } | 379 | } |
379 | } | 380 | } |
@@ -414,7 +415,6 @@ impl Ty { | |||
414 | // FIXME: report error | 415 | // FIXME: report error |
415 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), | 416 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), |
416 | }; | 417 | }; |
417 | |||
418 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) | 418 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) |
419 | } | 419 | } |
420 | 420 | ||
@@ -472,10 +472,10 @@ impl Ty { | |||
472 | // associated_type_shorthand_candidates does not do that | 472 | // associated_type_shorthand_candidates does not do that |
473 | let substs = substs.shift_bound_vars(ctx.in_binders); | 473 | let substs = substs.shift_bound_vars(ctx.in_binders); |
474 | // FIXME handle type parameters on the segment | 474 | // FIXME handle type parameters on the segment |
475 | return Some(Ty::Projection(ProjectionTy { | 475 | return Some(Ty::Alias(AliasTy::Projection(ProjectionTy { |
476 | associated_ty, | 476 | associated_ty, |
477 | parameters: substs, | 477 | parameters: substs, |
478 | })); | 478 | }))); |
479 | } | 479 | } |
480 | 480 | ||
481 | None | 481 | None |
@@ -676,7 +676,7 @@ impl GenericPredicate { | |||
676 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), | 676 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), |
677 | TypeParamLoweringMode::Variable => { | 677 | TypeParamLoweringMode::Variable => { |
678 | let idx = generics.param_idx(param_id).expect("matching generics"); | 678 | let idx = generics.param_idx(param_id).expect("matching generics"); |
679 | Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) | 679 | Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) |
680 | } | 680 | } |
681 | } | 681 | } |
682 | } | 682 | } |
@@ -750,7 +750,7 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
750 | preds.extend(GenericPredicate::from_type_bound( | 750 | preds.extend(GenericPredicate::from_type_bound( |
751 | ctx, | 751 | ctx, |
752 | bound, | 752 | bound, |
753 | Ty::Projection(projection_ty.clone()), | 753 | Ty::Alias(AliasTy::Projection(projection_ty.clone())), |
754 | )); | 754 | )); |
755 | } | 755 | } |
756 | preds | 756 | preds |
@@ -760,7 +760,7 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
760 | impl ReturnTypeImplTrait { | 760 | impl ReturnTypeImplTrait { |
761 | fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self { | 761 | fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self { |
762 | mark::hit!(lower_rpit); | 762 | mark::hit!(lower_rpit); |
763 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 763 | let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); |
764 | let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { | 764 | let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
765 | bounds | 765 | bounds |
766 | .iter() | 766 | .iter() |
@@ -984,7 +984,7 @@ pub(crate) fn generic_defaults_query( | |||
984 | // Each default can only refer to previous parameters. | 984 | // Each default can only refer to previous parameters. |
985 | ty.walk_mut_binders( | 985 | ty.walk_mut_binders( |
986 | &mut |ty, binders| match ty { | 986 | &mut |ty, binders| match ty { |
987 | Ty::Bound(BoundVar { debruijn, index }) if *debruijn == binders => { | 987 | Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { |
988 | if *index >= idx { | 988 | if *index >= idx { |
989 | // type variable default referring to parameter coming | 989 | // type variable default referring to parameter coming |
990 | // after it. This is forbidden (FIXME: report | 990 | // after it. This is forbidden (FIXME: report |
@@ -1017,7 +1017,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1017 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); | 1017 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); |
1018 | let generics = generics(db.upcast(), def.into()); | 1018 | let generics = generics(db.upcast(), def.into()); |
1019 | let num_binders = generics.len(); | 1019 | let num_binders = generics.len(); |
1020 | Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) | 1020 | Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | /// Build the declared type of a function. This should not need to look at the | 1023 | /// Build the declared type of a function. This should not need to look at the |
@@ -1025,7 +1025,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1025 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { | 1025 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { |
1026 | let generics = generics(db.upcast(), def.into()); | 1026 | let generics = generics(db.upcast(), def.into()); |
1027 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1027 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1028 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1028 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | /// Build the declared type of a const. | 1031 | /// Build the declared type of a const. |
@@ -1057,7 +1057,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS | |||
1057 | let params = | 1057 | let params = |
1058 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 1058 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
1059 | let ret = type_for_adt(db, def.into()); | 1059 | let ret = type_for_adt(db, def.into()); |
1060 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) | 1060 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | /// Build the type of a tuple struct constructor. | 1063 | /// Build the type of a tuple struct constructor. |
@@ -1068,7 +1068,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T | |||
1068 | } | 1068 | } |
1069 | let generics = generics(db.upcast(), def.into()); | 1069 | let generics = generics(db.upcast(), def.into()); |
1070 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1070 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1071 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1071 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { | 1074 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { |
@@ -1081,7 +1081,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) | |||
1081 | let params = | 1081 | let params = |
1082 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 1082 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
1083 | let ret = type_for_adt(db, def.parent.into()); | 1083 | let ret = type_for_adt(db, def.parent.into()); |
1084 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) | 1084 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) |
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | /// Build the type of a tuple enum variant constructor. | 1087 | /// Build the type of a tuple enum variant constructor. |
@@ -1093,13 +1093,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) - | |||
1093 | } | 1093 | } |
1094 | let generics = generics(db.upcast(), def.parent.into()); | 1094 | let generics = generics(db.upcast(), def.parent.into()); |
1095 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1095 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1096 | Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) | 1096 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1099 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { |
1100 | let generics = generics(db.upcast(), adt.into()); | 1100 | let generics = generics(db.upcast(), adt.into()); |
1101 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1101 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1102 | Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) | 1102 | Binders::new(substs.len(), Ty::Adt(adt, substs)) |
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | 1105 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { |
@@ -1107,10 +1107,10 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1107 | let resolver = t.resolver(db.upcast()); | 1107 | let resolver = t.resolver(db.upcast()); |
1108 | let ctx = | 1108 | let ctx = |
1109 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1109 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1110 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | ||
1111 | if db.type_alias_data(t).is_extern { | 1110 | if db.type_alias_data(t).is_extern { |
1112 | Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) | 1111 | Binders::new(0, Ty::ForeignType(t)) |
1113 | } else { | 1112 | } else { |
1113 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | ||
1114 | let type_ref = &db.type_alias_data(t).type_ref; | 1114 | 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)); | 1115 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
1116 | Binders::new(substs.len(), inner) | 1116 | Binders::new(substs.len(), inner) |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index b3d1fe9a4..dd5109d4e 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -7,11 +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 | builtin_type::{IntBitness, Signedness}, | 10 | lang_item::LangItemTarget, type_ref::Mutability, AdtId, AssocContainerId, AssocItemId, |
11 | lang_item::LangItemTarget, | 11 | FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId, |
12 | type_ref::Mutability, | ||
13 | AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, | ||
14 | TraitId, | ||
15 | }; | 12 | }; |
16 | use hir_expand::name::Name; | 13 | use hir_expand::name::Name; |
17 | use rustc_hash::{FxHashMap, FxHashSet}; | 14 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -19,17 +16,26 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
19 | use crate::{ | 16 | use crate::{ |
20 | autoderef, | 17 | autoderef, |
21 | db::HirDatabase, | 18 | db::HirDatabase, |
22 | primitive::{FloatBitness, FloatTy, IntTy}, | 19 | primitive::{self, FloatTy, IntTy, UintTy}, |
23 | utils::all_super_traits, | 20 | utils::all_super_traits, |
24 | ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Substs, TraitEnvironment, TraitRef, Ty, | 21 | Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment, |
25 | TyKind, TypeCtor, TypeWalk, | 22 | TraitRef, Ty, TypeWalk, |
26 | }; | 23 | }; |
27 | 24 | ||
28 | /// This is used as a key for indexing impls. | 25 | /// This is used as a key for indexing impls. |
29 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 26 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
30 | pub enum TyFingerprint { | 27 | pub enum TyFingerprint { |
31 | Apply(TypeCtor), | 28 | Str, |
29 | Slice, | ||
30 | Array, | ||
31 | Never, | ||
32 | RawPtr(Mutability), | ||
33 | Scalar(Scalar), | ||
34 | Adt(AdtId), | ||
32 | Dyn(TraitId), | 35 | Dyn(TraitId), |
36 | Tuple(usize), | ||
37 | ForeignType(TypeAliasId), | ||
38 | FnPtr(usize, FnSig), | ||
33 | } | 39 | } |
34 | 40 | ||
35 | impl TyFingerprint { | 41 | impl TyFingerprint { |
@@ -37,68 +43,42 @@ impl TyFingerprint { | |||
37 | /// 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 |
38 | /// `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. |
39 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 45 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
40 | match ty { | 46 | let fp = match ty { |
41 | Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), | 47 | &Ty::Str => TyFingerprint::Str, |
42 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_)), | 48 | &Ty::Never => TyFingerprint::Never, |
43 | _ => None, | 49 | &Ty::Slice(..) => TyFingerprint::Slice, |
44 | } | 50 | &Ty::Array(..) => TyFingerprint::Array, |
51 | &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), | ||
52 | &Ty::Adt(adt, _) => TyFingerprint::Adt(adt), | ||
53 | &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | ||
54 | &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), | ||
55 | &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | ||
56 | &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), | ||
57 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
58 | _ => return None, | ||
59 | }; | ||
60 | Some(fp) | ||
45 | } | 61 | } |
46 | } | 62 | } |
47 | 63 | ||
48 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 64 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
49 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | 65 | TyFingerprint::Scalar(Scalar::Int(IntTy::I8)), |
50 | signedness: Signedness::Unsigned, | 66 | TyFingerprint::Scalar(Scalar::Int(IntTy::I16)), |
51 | bitness: IntBitness::X8, | 67 | TyFingerprint::Scalar(Scalar::Int(IntTy::I32)), |
52 | })), | 68 | TyFingerprint::Scalar(Scalar::Int(IntTy::I64)), |
53 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | 69 | TyFingerprint::Scalar(Scalar::Int(IntTy::I128)), |
54 | signedness: Signedness::Unsigned, | 70 | TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)), |
55 | bitness: IntBitness::X16, | 71 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)), |
56 | })), | 72 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)), |
57 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | 73 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)), |
58 | signedness: Signedness::Unsigned, | 74 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)), |
59 | bitness: IntBitness::X32, | 75 | TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)), |
60 | })), | 76 | TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)), |
61 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
62 | signedness: Signedness::Unsigned, | ||
63 | bitness: IntBitness::X64, | ||
64 | })), | ||
65 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
66 | signedness: Signedness::Unsigned, | ||
67 | bitness: IntBitness::X128, | ||
68 | })), | ||
69 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
70 | signedness: Signedness::Unsigned, | ||
71 | bitness: IntBitness::Xsize, | ||
72 | })), | ||
73 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
74 | signedness: Signedness::Signed, | ||
75 | bitness: IntBitness::X8, | ||
76 | })), | ||
77 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
78 | signedness: Signedness::Signed, | ||
79 | bitness: IntBitness::X16, | ||
80 | })), | ||
81 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
82 | signedness: Signedness::Signed, | ||
83 | bitness: IntBitness::X32, | ||
84 | })), | ||
85 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
86 | signedness: Signedness::Signed, | ||
87 | bitness: IntBitness::X64, | ||
88 | })), | ||
89 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
90 | signedness: Signedness::Signed, | ||
91 | bitness: IntBitness::X128, | ||
92 | })), | ||
93 | TyFingerprint::Apply(TypeCtor::Int(IntTy { | ||
94 | signedness: Signedness::Signed, | ||
95 | bitness: IntBitness::Xsize, | ||
96 | })), | ||
97 | ]; | 77 | ]; |
98 | 78 | ||
99 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ | 79 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ |
100 | TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), | 80 | TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)), |
101 | TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), | 81 | TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)), |
102 | ]; | 82 | ]; |
103 | 83 | ||
104 | /// Trait impls defined or available in some crate. | 84 | /// Trait impls defined or available in some crate. |
@@ -250,27 +230,29 @@ impl Ty { | |||
250 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 230 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
251 | 231 | ||
252 | let lang_item_targets = match self { | 232 | let lang_item_targets = match self { |
253 | Ty::Apply(a_ty) => match a_ty.ctor { | 233 | Ty::Adt(def_id, _) => { |
254 | TypeCtor::Adt(def_id) => { | 234 | return mod_to_crate_ids(def_id.module(db.upcast())); |
255 | return mod_to_crate_ids(def_id.module(db.upcast())); | 235 | } |
256 | } | 236 | Ty::ForeignType(type_alias_id) => { |
257 | TypeCtor::ForeignType(type_alias_id) => { | 237 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); |
258 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); | 238 | } |
259 | } | 239 | Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
260 | TypeCtor::Bool => lang_item_crate!("bool"), | 240 | Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), |
261 | TypeCtor::Char => lang_item_crate!("char"), | 241 | Ty::Scalar(Scalar::Float(f)) => match f { |
262 | TypeCtor::Float(f) => match f.bitness { | 242 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
263 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 243 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
264 | FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), | 244 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
265 | FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), | ||
266 | }, | ||
267 | TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()), | ||
268 | TypeCtor::Str => lang_item_crate!("str_alloc", "str"), | ||
269 | TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), | ||
270 | TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), | ||
271 | TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"), | ||
272 | _ => return None, | ||
273 | }, | 245 | }, |
246 | &Ty::Scalar(Scalar::Int(t)) => { | ||
247 | lang_item_crate!(primitive::int_ty_to_string(t)) | ||
248 | } | ||
249 | &Ty::Scalar(Scalar::Uint(t)) => { | ||
250 | lang_item_crate!(primitive::uint_ty_to_string(t)) | ||
251 | } | ||
252 | Ty::Str => lang_item_crate!("str_alloc", "str"), | ||
253 | Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | ||
254 | Ty::Raw(Mutability::Shared, _) => lang_item_crate!("const_ptr"), | ||
255 | Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | ||
274 | Ty::Dyn(_) => { | 256 | Ty::Dyn(_) => { |
275 | return self.dyn_trait().and_then(|trait_| { | 257 | return self.dyn_trait().and_then(|trait_| { |
276 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 258 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
@@ -447,7 +429,7 @@ fn iterate_method_candidates_with_autoref( | |||
447 | } | 429 | } |
448 | let refed = Canonical { | 430 | let refed = Canonical { |
449 | kinds: deref_chain[0].kinds.clone(), | 431 | kinds: deref_chain[0].kinds.clone(), |
450 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), | 432 | value: Ty::Ref(Mutability::Shared, Substs::single(deref_chain[0].value.clone())), |
451 | }; | 433 | }; |
452 | if iterate_method_candidates_by_receiver( | 434 | if iterate_method_candidates_by_receiver( |
453 | &refed, | 435 | &refed, |
@@ -463,7 +445,7 @@ fn iterate_method_candidates_with_autoref( | |||
463 | } | 445 | } |
464 | let ref_muted = Canonical { | 446 | let ref_muted = Canonical { |
465 | kinds: deref_chain[0].kinds.clone(), | 447 | kinds: deref_chain[0].kinds.clone(), |
466 | value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), | 448 | value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), |
467 | }; | 449 | }; |
468 | if iterate_method_candidates_by_receiver( | 450 | if iterate_method_candidates_by_receiver( |
469 | &ref_muted, | 451 | &ref_muted, |
@@ -685,7 +667,7 @@ pub(crate) fn inherent_impl_substs( | |||
685 | .build(); | 667 | .build(); |
686 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 668 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); |
687 | let mut kinds = self_ty.kinds.to_vec(); | 669 | let mut kinds = self_ty.kinds.to_vec(); |
688 | kinds.extend(iter::repeat(TyKind::General).take(vars.len())); | 670 | kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len())); |
689 | let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; | 671 | let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; |
690 | let substs = super::infer::unify(&tys); | 672 | let substs = super::infer::unify(&tys); |
691 | // We only want the substs for the vars we added, not the ones from self_ty. | 673 | // We only want the substs for the vars we added, not the ones from self_ty. |
@@ -701,7 +683,7 @@ pub(crate) fn inherent_impl_substs( | |||
701 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { | 683 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { |
702 | s.fold_binders( | 684 | s.fold_binders( |
703 | &mut |ty, binders| { | 685 | &mut |ty, binders| { |
704 | if let Ty::Bound(bound) = &ty { | 686 | if let Ty::BoundVar(bound) = &ty { |
705 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 687 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { |
706 | Ty::Unknown | 688 | Ty::Unknown |
707 | } else { | 689 | } else { |
@@ -777,7 +759,7 @@ fn generic_implements_goal( | |||
777 | .push(self_ty.value) | 759 | .push(self_ty.value) |
778 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) | 760 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) |
779 | .build(); | 761 | .build(); |
780 | kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1)); | 762 | kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); |
781 | let trait_ref = TraitRef { trait_, substs }; | 763 | let trait_ref = TraitRef { trait_, substs }; |
782 | let obligation = super::Obligation::Trait(trait_ref); | 764 | let obligation = super::Obligation::Trait(trait_ref); |
783 | Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } | 765 | Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } |
@@ -790,11 +772,9 @@ fn autoderef_method_receiver( | |||
790 | ) -> Vec<Canonical<Ty>> { | 772 | ) -> Vec<Canonical<Ty>> { |
791 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 773 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
792 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 774 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
793 | if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = | 775 | if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) { |
794 | deref_chain.last().map(|ty| &ty.value) | ||
795 | { | ||
796 | let kinds = deref_chain.last().unwrap().kinds.clone(); | 776 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
797 | let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); | 777 | let unsized_ty = Ty::Slice(parameters.clone()); |
798 | deref_chain.push(Canonical { value: unsized_ty, kinds }) | 778 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
799 | } | 779 | } |
800 | deref_chain | 780 | deref_chain |
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs index 0870874fc..bb9b8bbfc 100644 --- a/crates/hir_ty/src/op.rs +++ b/crates/hir_ty/src/op.rs | |||
@@ -1,27 +1,27 @@ | |||
1 | //! Helper functions for binary operator type inference. | 1 | //! Helper functions for binary operator type inference. |
2 | use chalk_ir::TyVariableKind; | ||
2 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; | 3 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; |
3 | 4 | ||
4 | use super::{InferTy, Ty, TypeCtor}; | 5 | use crate::{Scalar, Ty}; |
5 | use crate::ApplicationTy; | ||
6 | 6 | ||
7 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | 7 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { |
8 | match op { | 8 | match op { |
9 | BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), | 9 | BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::Scalar(Scalar::Bool), |
10 | BinaryOp::Assignment { .. } => Ty::unit(), | 10 | BinaryOp::Assignment { .. } => Ty::unit(), |
11 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { | 11 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { |
12 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 12 | Ty::Scalar(Scalar::Int(_)) |
13 | TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, | 13 | | Ty::Scalar(Scalar::Uint(_)) |
14 | _ => Ty::Unknown, | 14 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, |
15 | }, | 15 | Ty::InferenceVar(_, TyVariableKind::Integer) |
16 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 16 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, |
17 | _ => Ty::Unknown, | 17 | _ => Ty::Unknown, |
18 | }, | 18 | }, |
19 | BinaryOp::ArithOp(_) => match rhs_ty { | 19 | BinaryOp::ArithOp(_) => match rhs_ty { |
20 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 20 | Ty::Scalar(Scalar::Int(_)) |
21 | TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, | 21 | | Ty::Scalar(Scalar::Uint(_)) |
22 | _ => Ty::Unknown, | 22 | | Ty::Scalar(Scalar::Float(_)) => rhs_ty, |
23 | }, | 23 | Ty::InferenceVar(_, TyVariableKind::Integer) |
24 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, | 24 | | Ty::InferenceVar(_, TyVariableKind::Float) => rhs_ty, |
25 | _ => Ty::Unknown, | 25 | _ => Ty::Unknown, |
26 | }, | 26 | }, |
27 | } | 27 | } |
@@ -29,29 +29,23 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | |||
29 | 29 | ||
30 | pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | 30 | pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { |
31 | match op { | 31 | match op { |
32 | BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), | 32 | BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool), |
33 | BinaryOp::Assignment { op: None } => lhs_ty, | 33 | BinaryOp::Assignment { op: None } => lhs_ty, |
34 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { | 34 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { |
35 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 35 | Ty::Scalar(_) | Ty::Str => lhs_ty, |
36 | TypeCtor::Int(..) | 36 | Ty::InferenceVar(_, TyVariableKind::Integer) |
37 | | TypeCtor::Float(..) | 37 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, |
38 | | TypeCtor::Str | ||
39 | | TypeCtor::Char | ||
40 | | TypeCtor::Bool => lhs_ty, | ||
41 | _ => Ty::Unknown, | ||
42 | }, | ||
43 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | ||
44 | _ => Ty::Unknown, | 38 | _ => Ty::Unknown, |
45 | }, | 39 | }, |
46 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, | 40 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, |
47 | BinaryOp::CmpOp(CmpOp::Ord { .. }) | 41 | BinaryOp::CmpOp(CmpOp::Ord { .. }) |
48 | | BinaryOp::Assignment { op: Some(_) } | 42 | | BinaryOp::Assignment { op: Some(_) } |
49 | | BinaryOp::ArithOp(_) => match lhs_ty { | 43 | | BinaryOp::ArithOp(_) => match lhs_ty { |
50 | Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { | 44 | Ty::Scalar(Scalar::Int(_)) |
51 | TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, | 45 | | Ty::Scalar(Scalar::Uint(_)) |
52 | _ => Ty::Unknown, | 46 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, |
53 | }, | 47 | Ty::InferenceVar(_, TyVariableKind::Integer) |
54 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, | 48 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, |
55 | _ => Ty::Unknown, | 49 | _ => Ty::Unknown, |
56 | }, | 50 | }, |
57 | } | 51 | } |
diff --git a/crates/hir_ty/src/primitive.rs b/crates/hir_ty/src/primitive.rs index 37966b709..2449addfb 100644 --- a/crates/hir_ty/src/primitive.rs +++ b/crates/hir_ty/src/primitive.rs | |||
@@ -3,137 +3,63 @@ | |||
3 | //! * during type inference, they can be uncertain (ie, `let x = 92;`) | 3 | //! * during type inference, they can be uncertain (ie, `let x = 92;`) |
4 | //! * they don't belong to any particular crate. | 4 | //! * they don't belong to any particular crate. |
5 | 5 | ||
6 | use std::fmt; | 6 | pub use chalk_ir::{FloatTy, IntTy, UintTy}; |
7 | 7 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}; | |
8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; | 8 | |
9 | 9 | pub fn int_ty_to_string(ty: IntTy) -> &'static str { | |
10 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] | 10 | match ty { |
11 | pub struct IntTy { | 11 | IntTy::Isize => "isize", |
12 | pub signedness: Signedness, | 12 | IntTy::I8 => "i8", |
13 | pub bitness: IntBitness, | 13 | IntTy::I16 => "i16", |
14 | } | 14 | IntTy::I32 => "i32", |
15 | 15 | IntTy::I64 => "i64", | |
16 | impl fmt::Debug for IntTy { | 16 | IntTy::I128 => "i128", |
17 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
18 | fmt::Display::fmt(self, f) | ||
19 | } | ||
20 | } | ||
21 | |||
22 | impl fmt::Display for IntTy { | ||
23 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
24 | write!(f, "{}", self.ty_to_string()) | ||
25 | } | ||
26 | } | ||
27 | |||
28 | impl IntTy { | ||
29 | pub fn isize() -> IntTy { | ||
30 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } | ||
31 | } | ||
32 | |||
33 | pub fn i8() -> IntTy { | ||
34 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } | ||
35 | } | ||
36 | |||
37 | pub fn i16() -> IntTy { | ||
38 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } | ||
39 | } | ||
40 | |||
41 | pub fn i32() -> IntTy { | ||
42 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } | ||
43 | } | ||
44 | |||
45 | pub fn i64() -> IntTy { | ||
46 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } | ||
47 | } | ||
48 | |||
49 | pub fn i128() -> IntTy { | ||
50 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } | ||
51 | } | 17 | } |
52 | |||
53 | pub fn usize() -> IntTy { | ||
54 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } | ||
55 | } | ||
56 | |||
57 | pub fn u8() -> IntTy { | ||
58 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } | ||
59 | } | ||
60 | |||
61 | pub fn u16() -> IntTy { | ||
62 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } | ||
63 | } | ||
64 | |||
65 | pub fn u32() -> IntTy { | ||
66 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } | ||
67 | } | ||
68 | |||
69 | pub fn u64() -> IntTy { | ||
70 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } | ||
71 | } | ||
72 | |||
73 | pub fn u128() -> IntTy { | ||
74 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } | ||
75 | } | ||
76 | |||
77 | pub fn ty_to_string(self) -> &'static str { | ||
78 | match (self.signedness, self.bitness) { | ||
79 | (Signedness::Signed, IntBitness::Xsize) => "isize", | ||
80 | (Signedness::Signed, IntBitness::X8) => "i8", | ||
81 | (Signedness::Signed, IntBitness::X16) => "i16", | ||
82 | (Signedness::Signed, IntBitness::X32) => "i32", | ||
83 | (Signedness::Signed, IntBitness::X64) => "i64", | ||
84 | (Signedness::Signed, IntBitness::X128) => "i128", | ||
85 | (Signedness::Unsigned, IntBitness::Xsize) => "usize", | ||
86 | (Signedness::Unsigned, IntBitness::X8) => "u8", | ||
87 | (Signedness::Unsigned, IntBitness::X16) => "u16", | ||
88 | (Signedness::Unsigned, IntBitness::X32) => "u32", | ||
89 | (Signedness::Unsigned, IntBitness::X64) => "u64", | ||
90 | (Signedness::Unsigned, IntBitness::X128) => "u128", | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||
96 | pub struct FloatTy { | ||
97 | pub bitness: FloatBitness, | ||
98 | } | 18 | } |
99 | 19 | ||
100 | impl fmt::Debug for FloatTy { | 20 | pub fn uint_ty_to_string(ty: UintTy) -> &'static str { |
101 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 21 | match ty { |
102 | fmt::Display::fmt(self, f) | 22 | UintTy::Usize => "usize", |
23 | UintTy::U8 => "u8", | ||
24 | UintTy::U16 => "u16", | ||
25 | UintTy::U32 => "u32", | ||
26 | UintTy::U64 => "u64", | ||
27 | UintTy::U128 => "u128", | ||
103 | } | 28 | } |
104 | } | 29 | } |
105 | 30 | ||
106 | impl fmt::Display for FloatTy { | 31 | pub fn float_ty_to_string(ty: FloatTy) -> &'static str { |
107 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 32 | match ty { |
108 | write!(f, "{}", self.ty_to_string()) | 33 | FloatTy::F32 => "f32", |
34 | FloatTy::F64 => "f64", | ||
109 | } | 35 | } |
110 | } | 36 | } |
111 | 37 | ||
112 | impl FloatTy { | 38 | pub(super) fn int_ty_from_builtin(t: BuiltinInt) -> IntTy { |
113 | pub fn f32() -> FloatTy { | 39 | match t { |
114 | FloatTy { bitness: FloatBitness::X32 } | 40 | BuiltinInt::Isize => IntTy::Isize, |
115 | } | 41 | BuiltinInt::I8 => IntTy::I8, |
116 | 42 | BuiltinInt::I16 => IntTy::I16, | |
117 | pub fn f64() -> FloatTy { | 43 | BuiltinInt::I32 => IntTy::I32, |
118 | FloatTy { bitness: FloatBitness::X64 } | 44 | BuiltinInt::I64 => IntTy::I64, |
119 | } | 45 | BuiltinInt::I128 => IntTy::I128, |
120 | |||
121 | pub fn ty_to_string(self) -> &'static str { | ||
122 | match self.bitness { | ||
123 | FloatBitness::X32 => "f32", | ||
124 | FloatBitness::X64 => "f64", | ||
125 | } | ||
126 | } | 46 | } |
127 | } | 47 | } |
128 | 48 | ||
129 | impl From<BuiltinInt> for IntTy { | 49 | pub(super) fn uint_ty_from_builtin(t: BuiltinUint) -> UintTy { |
130 | fn from(t: BuiltinInt) -> Self { | 50 | match t { |
131 | IntTy { signedness: t.signedness, bitness: t.bitness } | 51 | BuiltinUint::Usize => UintTy::Usize, |
52 | BuiltinUint::U8 => UintTy::U8, | ||
53 | BuiltinUint::U16 => UintTy::U16, | ||
54 | BuiltinUint::U32 => UintTy::U32, | ||
55 | BuiltinUint::U64 => UintTy::U64, | ||
56 | BuiltinUint::U128 => UintTy::U128, | ||
132 | } | 57 | } |
133 | } | 58 | } |
134 | 59 | ||
135 | impl From<BuiltinFloat> for FloatTy { | 60 | pub(super) fn float_ty_from_builtin(t: BuiltinFloat) -> FloatTy { |
136 | fn from(t: BuiltinFloat) -> Self { | 61 | match t { |
137 | FloatTy { bitness: t.bitness } | 62 | BuiltinFloat::F32 => FloatTy::F32, |
63 | BuiltinFloat::F64 => FloatTy::F64, | ||
138 | } | 64 | } |
139 | } | 65 | } |
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 12ec4657b..2947857a5 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -2491,3 +2491,58 @@ fn inner_use_enum_rename() { | |||
2491 | "#]], | 2491 | "#]], |
2492 | ) | 2492 | ) |
2493 | } | 2493 | } |
2494 | |||
2495 | #[test] | ||
2496 | fn box_into_vec() { | ||
2497 | check_infer( | ||
2498 | r#" | ||
2499 | #[lang = "sized"] | ||
2500 | pub trait Sized {} | ||
2501 | |||
2502 | #[lang = "unsize"] | ||
2503 | pub trait Unsize<T: ?Sized> {} | ||
2504 | |||
2505 | #[lang = "coerce_unsized"] | ||
2506 | pub trait CoerceUnsized<T> {} | ||
2507 | |||
2508 | pub unsafe trait Allocator {} | ||
2509 | |||
2510 | pub struct Global; | ||
2511 | unsafe impl Allocator for Global {} | ||
2512 | |||
2513 | #[lang = "owned_box"] | ||
2514 | #[fundamental] | ||
2515 | pub struct Box<T: ?Sized, A: Allocator = Global>; | ||
2516 | |||
2517 | impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {} | ||
2518 | |||
2519 | pub struct Vec<T, A: Allocator = Global> {} | ||
2520 | |||
2521 | #[lang = "slice"] | ||
2522 | impl<T> [T] {} | ||
2523 | |||
2524 | #[lang = "slice_alloc"] | ||
2525 | impl<T> [T] { | ||
2526 | pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> { | ||
2527 | unimplemented!() | ||
2528 | } | ||
2529 | } | ||
2530 | |||
2531 | fn test() { | ||
2532 | let vec = <[_]>::into_vec(box [1i32]); | ||
2533 | } | ||
2534 | "#, | ||
2535 | expect![[r#" | ||
2536 | 569..573 'self': Box<[T], A> | ||
2537 | 602..634 '{ ... }': Vec<T, A> | ||
2538 | 612..628 'unimpl...ted!()': Vec<T, A> | ||
2539 | 648..694 '{ ...2]); }': () | ||
2540 | 658..661 'vec': Vec<i32, Global> | ||
2541 | 664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global> | ||
2542 | 664..691 '<[_]>:...1i32])': Vec<i32, Global> | ||
2543 | 680..690 'box [1i32]': Box<[i32; _], Global> | ||
2544 | 684..690 '[1i32]': [i32; _] | ||
2545 | 685..689 '1i32': i32 | ||
2546 | "#]], | ||
2547 | ) | ||
2548 | } | ||
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index dfa51896b..e4cdb6d53 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -129,7 +129,7 @@ pub(crate) fn trait_solve_query( | |||
129 | log::info!("trait_solve_query({})", goal.value.value.display(db)); | 129 | log::info!("trait_solve_query({})", goal.value.value.display(db)); |
130 | 130 | ||
131 | if let Obligation::Projection(pred) = &goal.value.value { | 131 | if let Obligation::Projection(pred) = &goal.value.value { |
132 | if let Ty::Bound(_) = &pred.projection_ty.parameters[0] { | 132 | if let Ty::BoundVar(_) = &pred.projection_ty.parameters[0] { |
133 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible | 133 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible |
134 | return Some(Solution::Ambig(Guidance::Unknown)); | 134 | return Some(Solution::Ambig(Guidance::Unknown)); |
135 | } | 135 | } |
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index d74c83737..e513fa8f4 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -19,8 +19,8 @@ use crate::{ | |||
19 | display::HirDisplay, | 19 | display::HirDisplay, |
20 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 20 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
21 | utils::generics, | 21 | utils::generics, |
22 | BoundVar, CallableDefId, DebruijnIndex, FnSig, GenericPredicate, ProjectionPredicate, | 22 | BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate, |
23 | ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 23 | ProjectionTy, Substs, TraitRef, Ty, |
24 | }; | 24 | }; |
25 | use mapping::{ | 25 | use mapping::{ |
26 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, | 26 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, |
@@ -90,7 +90,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
90 | ty: &Ty, | 90 | ty: &Ty, |
91 | binders: &CanonicalVarKinds<Interner>, | 91 | binders: &CanonicalVarKinds<Interner>, |
92 | ) -> Option<chalk_ir::TyVariableKind> { | 92 | ) -> Option<chalk_ir::TyVariableKind> { |
93 | if let Ty::Bound(bv) = ty { | 93 | if let Ty::BoundVar(bv) = ty { |
94 | let binders = binders.as_slice(&Interner); | 94 | let binders = binders.as_slice(&Interner); |
95 | if bv.debruijn == DebruijnIndex::INNERMOST { | 95 | if bv.debruijn == DebruijnIndex::INNERMOST { |
96 | if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { | 96 | if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { |
@@ -220,18 +220,18 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
220 | let impl_bound = GenericPredicate::Implemented(TraitRef { | 220 | let impl_bound = GenericPredicate::Implemented(TraitRef { |
221 | trait_: future_trait, | 221 | trait_: future_trait, |
222 | // Self type as the first parameter. | 222 | // Self type as the first parameter. |
223 | substs: Substs::single(Ty::Bound(BoundVar { | 223 | substs: Substs::single(Ty::BoundVar(BoundVar { |
224 | debruijn: DebruijnIndex::INNERMOST, | 224 | debruijn: DebruijnIndex::INNERMOST, |
225 | index: 0, | 225 | index: 0, |
226 | })), | 226 | })), |
227 | }); | 227 | }); |
228 | let proj_bound = GenericPredicate::Projection(ProjectionPredicate { | 228 | let proj_bound = GenericPredicate::Projection(ProjectionPredicate { |
229 | // The parameter of the opaque type. | 229 | // The parameter of the opaque type. |
230 | ty: Ty::Bound(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }), | 230 | ty: Ty::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }), |
231 | projection_ty: ProjectionTy { | 231 | projection_ty: ProjectionTy { |
232 | associated_ty: future_output, | 232 | associated_ty: future_output, |
233 | // Self type as the first parameter. | 233 | // Self type as the first parameter. |
234 | parameters: Substs::single(Ty::Bound(BoundVar::new( | 234 | parameters: Substs::single(Ty::BoundVar(BoundVar::new( |
235 | DebruijnIndex::INNERMOST, | 235 | DebruijnIndex::INNERMOST, |
236 | 0, | 236 | 0, |
237 | ))), | 237 | ))), |
@@ -286,9 +286,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
286 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { | 286 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { |
287 | let sig_ty: Ty = | 287 | let sig_ty: Ty = |
288 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); | 288 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); |
289 | let sig = FnSig::from_fn_ptr_substs( | 289 | let sig = CallableSig::from_substs( |
290 | &sig_ty.substs().expect("first closure param should be fn ptr"), | 290 | &sig_ty.substs().expect("first closure param should be fn ptr"), |
291 | false, | ||
292 | ); | 291 | ); |
293 | let io = rust_ir::FnDefInputsAndOutputDatum { | 292 | let io = rust_ir::FnDefInputsAndOutputDatum { |
294 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), | 293 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), |
@@ -393,7 +392,7 @@ pub(crate) fn associated_ty_data_query( | |||
393 | let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); | 392 | let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); |
394 | let ctx = crate::TyLoweringContext::new(db, &resolver) | 393 | let ctx = crate::TyLoweringContext::new(db, &resolver) |
395 | .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); | 394 | .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); |
396 | let self_ty = Ty::Bound(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)); | 395 | let self_ty = Ty::BoundVar(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)); |
397 | let bounds = type_alias_data | 396 | let bounds = type_alias_data |
398 | .bounds | 397 | .bounds |
399 | .iter() | 398 | .iter() |
@@ -489,10 +488,11 @@ pub(crate) fn struct_datum_query( | |||
489 | struct_id: AdtId, | 488 | struct_id: AdtId, |
490 | ) -> Arc<StructDatum> { | 489 | ) -> Arc<StructDatum> { |
491 | debug!("struct_datum {:?}", struct_id); | 490 | debug!("struct_datum {:?}", struct_id); |
492 | let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id)); | 491 | let adt_id = from_chalk(db, struct_id); |
492 | let type_ctor = Ty::Adt(adt_id, Substs::empty()); | ||
493 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | 493 | debug!("struct {:?} = {:?}", struct_id, type_ctor); |
494 | let num_params = type_ctor.num_ty_params(db); | 494 | let num_params = generics(db.upcast(), adt_id.into()).len(); |
495 | let upstream = type_ctor.krate(db) != Some(krate); | 495 | let upstream = adt_id.module(db.upcast()).krate() != krate; |
496 | let where_clauses = type_ctor | 496 | let where_clauses = type_ctor |
497 | .as_generic_def() | 497 | .as_generic_def() |
498 | .map(|generic_def| { | 498 | .map(|generic_def| { |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 8700d664e..6e6055d80 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -4,7 +4,7 @@ | |||
4 | //! conversions. | 4 | //! conversions. |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{ |
7 | cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, | 7 | cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, |
8 | UniverseIndex, | 8 | UniverseIndex, |
9 | }; | 9 | }; |
10 | use chalk_solve::rust_ir; | 10 | use chalk_solve::rust_ir; |
@@ -14,10 +14,10 @@ use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, Type | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, | 17 | primitive::UintTy, |
18 | traits::{Canonical, Obligation}, | 18 | traits::{Canonical, Obligation}, |
19 | ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, | 19 | AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, |
20 | ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, | 20 | OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | use super::interner::*; | 23 | use super::interner::*; |
@@ -27,88 +27,68 @@ impl ToChalk for Ty { | |||
27 | type Chalk = chalk_ir::Ty<Interner>; | 27 | type Chalk = chalk_ir::Ty<Interner>; |
28 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { | 28 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { |
29 | match self { | 29 | match self { |
30 | Ty::Apply(apply_ty) => match apply_ty.ctor { | 30 | Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters), |
31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), | 31 | Ty::Array(parameters) => array_to_chalk(db, parameters), |
32 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), | 32 | Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => { |
33 | TypeCtor::FnPtr { num_args: _, is_varargs } => { | 33 | let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); |
34 | let substitution = | 34 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { |
35 | chalk_ir::FnSubst(apply_ty.parameters.to_chalk(db).shifted_in(&Interner)); | 35 | num_binders: 0, |
36 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | 36 | sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic }, |
37 | num_binders: 0, | 37 | substitution, |
38 | sig: chalk_ir::FnSig { | 38 | }) |
39 | abi: (), | 39 | .intern(&Interner) |
40 | safety: chalk_ir::Safety::Safe, | 40 | } |
41 | variadic: is_varargs, | 41 | Ty::AssociatedType(type_alias, substs) => { |
42 | }, | 42 | let assoc_type = TypeAliasAsAssocType(type_alias); |
43 | substitution, | 43 | let assoc_type_id = assoc_type.to_chalk(db); |
44 | }) | 44 | let substitution = substs.to_chalk(db); |
45 | .intern(&Interner) | 45 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) |
46 | } | 46 | } |
47 | TypeCtor::AssociatedType(type_alias) => { | ||
48 | let assoc_type = TypeAliasAsAssocType(type_alias); | ||
49 | let assoc_type_id = assoc_type.to_chalk(db); | ||
50 | let substitution = apply_ty.parameters.to_chalk(db); | ||
51 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) | ||
52 | } | ||
53 | 47 | ||
54 | TypeCtor::OpaqueType(impl_trait_id) => { | 48 | Ty::OpaqueType(impl_trait_id, substs) => { |
55 | let id = impl_trait_id.to_chalk(db); | 49 | let id = impl_trait_id.to_chalk(db); |
56 | let substitution = apply_ty.parameters.to_chalk(db); | 50 | let substitution = substs.to_chalk(db); |
57 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) | 51 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) |
58 | } | 52 | } |
59 | 53 | ||
60 | TypeCtor::ForeignType(type_alias) => { | 54 | Ty::ForeignType(type_alias) => { |
61 | let foreign_type = TypeAliasAsForeignType(type_alias); | 55 | let foreign_type = TypeAliasAsForeignType(type_alias); |
62 | let foreign_type_id = foreign_type.to_chalk(db); | 56 | let foreign_type_id = foreign_type.to_chalk(db); |
63 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) | 57 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) |
64 | } | 58 | } |
65 | 59 | ||
66 | TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner), | 60 | Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), |
67 | TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner), | ||
68 | TypeCtor::Int(int_ty) => { | ||
69 | chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner) | ||
70 | } | ||
71 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => { | ||
72 | chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) | ||
73 | .intern(&Interner) | ||
74 | } | ||
75 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => { | ||
76 | chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) | ||
77 | .intern(&Interner) | ||
78 | } | ||
79 | 61 | ||
80 | TypeCtor::Tuple { cardinality } => { | 62 | Ty::Tuple(cardinality, substs) => { |
81 | let substitution = apply_ty.parameters.to_chalk(db); | 63 | let substitution = substs.to_chalk(db); |
82 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) | 64 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) |
83 | } | 65 | } |
84 | TypeCtor::RawPtr(mutability) => { | 66 | Ty::Raw(mutability, substs) => { |
85 | let ty = apply_ty.parameters[0].clone().to_chalk(db); | 67 | let ty = substs[0].clone().to_chalk(db); |
86 | chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) | 68 | chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) |
87 | } | 69 | } |
88 | TypeCtor::Slice => { | 70 | Ty::Slice(substs) => { |
89 | chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db)) | 71 | chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) |
90 | .intern(&Interner) | 72 | } |
91 | } | 73 | Ty::Str => chalk_ir::TyKind::Str.intern(&Interner), |
92 | TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner), | 74 | Ty::FnDef(callable_def, substs) => { |
93 | TypeCtor::FnDef(callable_def) => { | 75 | let id = callable_def.to_chalk(db); |
94 | let id = callable_def.to_chalk(db); | 76 | let substitution = substs.to_chalk(db); |
95 | let substitution = apply_ty.parameters.to_chalk(db); | 77 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) |
96 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) | 78 | } |
97 | } | 79 | Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), |
98 | TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner), | ||
99 | 80 | ||
100 | TypeCtor::Closure { def, expr } => { | 81 | Ty::Closure(def, expr, substs) => { |
101 | let closure_id = db.intern_closure((def, expr)); | 82 | let closure_id = db.intern_closure((def, expr)); |
102 | let substitution = apply_ty.parameters.to_chalk(db); | 83 | let substitution = substs.to_chalk(db); |
103 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) | 84 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) |
104 | } | 85 | } |
105 | 86 | ||
106 | TypeCtor::Adt(adt_id) => { | 87 | Ty::Adt(adt_id, substs) => { |
107 | let substitution = apply_ty.parameters.to_chalk(db); | 88 | let substitution = substs.to_chalk(db); |
108 | chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) | 89 | chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) |
109 | } | 90 | } |
110 | }, | 91 | Ty::Alias(AliasTy::Projection(proj_ty)) => { |
111 | Ty::Projection(proj_ty) => { | ||
112 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); | 92 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); |
113 | let substitution = proj_ty.parameters.to_chalk(db); | 93 | let substitution = proj_ty.parameters.to_chalk(db); |
114 | chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { | 94 | chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { |
@@ -126,8 +106,8 @@ impl ToChalk for Ty { | |||
126 | } | 106 | } |
127 | .to_ty::<Interner>(&Interner) | 107 | .to_ty::<Interner>(&Interner) |
128 | } | 108 | } |
129 | Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), | 109 | Ty::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), |
130 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), | 110 | Ty::InferenceVar(..) => panic!("uncanonicalized infer ty"), |
131 | Ty::Dyn(predicates) => { | 111 | Ty::Dyn(predicates) => { |
132 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( | 112 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( |
133 | &Interner, | 113 | &Interner, |
@@ -139,7 +119,7 @@ impl ToChalk for Ty { | |||
139 | }; | 119 | }; |
140 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) | 120 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) |
141 | } | 121 | } |
142 | Ty::Opaque(opaque_ty) => { | 122 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { |
143 | let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); | 123 | let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); |
144 | let substitution = opaque_ty.parameters.to_chalk(db); | 124 | let substitution = opaque_ty.parameters.to_chalk(db); |
145 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { | 125 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { |
@@ -154,9 +134,7 @@ impl ToChalk for Ty { | |||
154 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { | 134 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { |
155 | match chalk.data(&Interner).kind.clone() { | 135 | match chalk.data(&Interner).kind.clone() { |
156 | chalk_ir::TyKind::Error => Ty::Unknown, | 136 | chalk_ir::TyKind::Error => Ty::Unknown, |
157 | chalk_ir::TyKind::Array(ty, _size) => { | 137 | chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))), |
158 | Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty))) | ||
159 | } | ||
160 | chalk_ir::TyKind::Placeholder(idx) => { | 138 | chalk_ir::TyKind::Placeholder(idx) => { |
161 | assert_eq!(idx.ui, UniverseIndex::ROOT); | 139 | assert_eq!(idx.ui, UniverseIndex::ROOT); |
162 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( | 140 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( |
@@ -168,12 +146,12 @@ impl ToChalk for Ty { | |||
168 | let associated_ty = | 146 | let associated_ty = |
169 | from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; | 147 | from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; |
170 | let parameters = from_chalk(db, proj.substitution); | 148 | let parameters = from_chalk(db, proj.substitution); |
171 | Ty::Projection(ProjectionTy { associated_ty, parameters }) | 149 | Ty::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters })) |
172 | } | 150 | } |
173 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { | 151 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { |
174 | let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); | 152 | let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); |
175 | let parameters = from_chalk(db, opaque_ty.substitution); | 153 | let parameters = from_chalk(db, opaque_ty.substitution); |
176 | Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) | 154 | Ty::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })) |
177 | } | 155 | } |
178 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | 156 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { |
179 | num_binders, | 157 | num_binders, |
@@ -182,19 +160,17 @@ impl ToChalk for Ty { | |||
182 | .. | 160 | .. |
183 | }) => { | 161 | }) => { |
184 | assert_eq!(num_binders, 0); | 162 | assert_eq!(num_binders, 0); |
185 | let parameters: Substs = from_chalk( | 163 | let substs: Substs = from_chalk( |
186 | db, | 164 | db, |
187 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), | 165 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), |
188 | ); | 166 | ); |
189 | Ty::Apply(ApplicationTy { | 167 | Ty::Function(FnPointer { |
190 | ctor: TypeCtor::FnPtr { | 168 | num_args: (substs.len() - 1), |
191 | num_args: (parameters.len() - 1) as u16, | 169 | sig: FnSig { variadic }, |
192 | is_varargs: variadic, | 170 | substs, |
193 | }, | ||
194 | parameters, | ||
195 | }) | 171 | }) |
196 | } | 172 | } |
197 | chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), | 173 | chalk_ir::TyKind::BoundVar(idx) => Ty::BoundVar(idx), |
198 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, | 174 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, |
199 | chalk_ir::TyKind::Dyn(where_clauses) => { | 175 | chalk_ir::TyKind::Dyn(where_clauses) => { |
200 | assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); | 176 | assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); |
@@ -207,75 +183,49 @@ impl ToChalk for Ty { | |||
207 | Ty::Dyn(predicates) | 183 | Ty::Dyn(predicates) |
208 | } | 184 | } |
209 | 185 | ||
210 | chalk_ir::TyKind::Adt(struct_id, subst) => { | 186 | chalk_ir::TyKind::Adt(struct_id, subst) => Ty::Adt(struct_id.0, from_chalk(db, subst)), |
211 | apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst) | 187 | chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType( |
212 | } | 188 | from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0, |
213 | chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk( | 189 | from_chalk(db, subst), |
214 | db, | ||
215 | TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0), | ||
216 | subst, | ||
217 | ), | 190 | ), |
191 | |||
218 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { | 192 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { |
219 | apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) | 193 | Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst)) |
220 | } | 194 | } |
221 | 195 | ||
222 | chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool), | 196 | chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar), |
223 | chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char), | ||
224 | chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy { | ||
225 | signedness: Signedness::Signed, | ||
226 | bitness: bitness_from_chalk_int(int_ty), | ||
227 | })), | ||
228 | chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy { | ||
229 | signedness: Signedness::Unsigned, | ||
230 | bitness: bitness_from_chalk_uint(uint_ty), | ||
231 | })), | ||
232 | chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { | ||
233 | Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })) | ||
234 | } | ||
235 | chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { | ||
236 | Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })) | ||
237 | } | ||
238 | chalk_ir::TyKind::Tuple(cardinality, subst) => { | 197 | chalk_ir::TyKind::Tuple(cardinality, subst) => { |
239 | apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) | 198 | Ty::Tuple(cardinality, from_chalk(db, subst)) |
240 | } | 199 | } |
241 | chalk_ir::TyKind::Raw(mutability, ty) => { | 200 | chalk_ir::TyKind::Raw(mutability, ty) => { |
242 | Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty)) | 201 | Ty::Raw(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) |
243 | } | 202 | } |
244 | chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)), | 203 | chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), |
245 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { | 204 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { |
246 | Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty)) | 205 | Ty::Ref(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) |
247 | } | 206 | } |
248 | chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str), | 207 | chalk_ir::TyKind::Str => Ty::Str, |
249 | chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never), | 208 | chalk_ir::TyKind::Never => Ty::Never, |
250 | 209 | ||
251 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { | 210 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { |
252 | let callable_def = from_chalk(db, fn_def_id); | 211 | Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst)) |
253 | apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst) | ||
254 | } | 212 | } |
255 | 213 | ||
256 | chalk_ir::TyKind::Closure(id, subst) => { | 214 | chalk_ir::TyKind::Closure(id, subst) => { |
257 | let id: crate::db::ClosureId = id.into(); | 215 | let id: crate::db::ClosureId = id.into(); |
258 | let (def, expr) = db.lookup_intern_closure(id); | 216 | let (def, expr) = db.lookup_intern_closure(id); |
259 | apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst) | 217 | Ty::Closure(def, expr, from_chalk(db, subst)) |
260 | } | 218 | } |
261 | 219 | ||
262 | chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType( | 220 | chalk_ir::TyKind::Foreign(foreign_def_id) => { |
263 | from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, | 221 | Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0) |
264 | )), | 222 | } |
265 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME | 223 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME |
266 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME | 224 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME |
267 | } | 225 | } |
268 | } | 226 | } |
269 | } | 227 | } |
270 | 228 | ||
271 | fn apply_ty_from_chalk( | ||
272 | db: &dyn HirDatabase, | ||
273 | ctor: TypeCtor, | ||
274 | subst: chalk_ir::Substitution<Interner>, | ||
275 | ) -> Ty { | ||
276 | Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) }) | ||
277 | } | ||
278 | |||
279 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a | 229 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a |
280 | /// fake lifetime here, because Chalks built-in logic may expect it to be there. | 230 | /// fake lifetime here, because Chalks built-in logic may expect it to be there. |
281 | fn ref_to_chalk( | 231 | fn ref_to_chalk( |
@@ -292,8 +242,7 @@ fn ref_to_chalk( | |||
292 | /// fake constant here, because Chalks built-in logic may expect it to be there. | 242 | /// fake constant here, because Chalks built-in logic may expect it to be there. |
293 | fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { | 243 | fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { |
294 | let arg = subst[0].clone().to_chalk(db); | 244 | let arg = subst[0].clone().to_chalk(db); |
295 | let usize_ty = | 245 | let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); |
296 | chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner); | ||
297 | let const_ = chalk_ir::ConstData { | 246 | let const_ = chalk_ir::ConstData { |
298 | ty: usize_ty, | 247 | ty: usize_ty, |
299 | value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), | 248 | value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), |
@@ -364,55 +313,6 @@ impl ToChalk for OpaqueTyId { | |||
364 | } | 313 | } |
365 | } | 314 | } |
366 | 315 | ||
367 | fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { | ||
368 | use chalk_ir::UintTy; | ||
369 | |||
370 | match uint_ty { | ||
371 | UintTy::Usize => IntBitness::Xsize, | ||
372 | UintTy::U8 => IntBitness::X8, | ||
373 | UintTy::U16 => IntBitness::X16, | ||
374 | UintTy::U32 => IntBitness::X32, | ||
375 | UintTy::U64 => IntBitness::X64, | ||
376 | UintTy::U128 => IntBitness::X128, | ||
377 | } | ||
378 | } | ||
379 | |||
380 | fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness { | ||
381 | use chalk_ir::IntTy; | ||
382 | |||
383 | match int_ty { | ||
384 | IntTy::Isize => IntBitness::Xsize, | ||
385 | IntTy::I8 => IntBitness::X8, | ||
386 | IntTy::I16 => IntBitness::X16, | ||
387 | IntTy::I32 => IntBitness::X32, | ||
388 | IntTy::I64 => IntBitness::X64, | ||
389 | IntTy::I128 => IntBitness::X128, | ||
390 | } | ||
391 | } | ||
392 | |||
393 | fn int_ty_to_chalk(int_ty: IntTy) -> Scalar { | ||
394 | use chalk_ir::{IntTy, UintTy}; | ||
395 | |||
396 | match int_ty.signedness { | ||
397 | Signedness::Signed => Scalar::Int(match int_ty.bitness { | ||
398 | IntBitness::Xsize => IntTy::Isize, | ||
399 | IntBitness::X8 => IntTy::I8, | ||
400 | IntBitness::X16 => IntTy::I16, | ||
401 | IntBitness::X32 => IntTy::I32, | ||
402 | IntBitness::X64 => IntTy::I64, | ||
403 | IntBitness::X128 => IntTy::I128, | ||
404 | }), | ||
405 | Signedness::Unsigned => Scalar::Uint(match int_ty.bitness { | ||
406 | IntBitness::Xsize => UintTy::Usize, | ||
407 | IntBitness::X8 => UintTy::U8, | ||
408 | IntBitness::X16 => UintTy::U16, | ||
409 | IntBitness::X32 => UintTy::U32, | ||
410 | IntBitness::X64 => UintTy::U64, | ||
411 | IntBitness::X128 => UintTy::U128, | ||
412 | }), | ||
413 | } | ||
414 | } | ||
415 | |||
416 | impl ToChalk for Mutability { | 316 | impl ToChalk for Mutability { |
417 | type Chalk = chalk_ir::Mutability; | 317 | type Chalk = chalk_ir::Mutability; |
418 | fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { | 318 | fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { |
@@ -632,20 +532,12 @@ where | |||
632 | type Chalk = chalk_ir::Canonical<T::Chalk>; | 532 | type Chalk = chalk_ir::Canonical<T::Chalk>; |
633 | 533 | ||
634 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { | 534 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { |
635 | let kinds = self | 535 | let kinds = self.kinds.iter().map(|&tk| { |
636 | .kinds | 536 | chalk_ir::CanonicalVarKind::new( |
637 | .iter() | 537 | chalk_ir::VariableKind::Ty(tk), |
638 | .map(|k| match k { | 538 | chalk_ir::UniverseIndex::ROOT, |
639 | TyKind::General => chalk_ir::TyVariableKind::General, | 539 | ) |
640 | TyKind::Integer => chalk_ir::TyVariableKind::Integer, | 540 | }); |
641 | TyKind::Float => chalk_ir::TyVariableKind::Float, | ||
642 | }) | ||
643 | .map(|tk| { | ||
644 | chalk_ir::CanonicalVarKind::new( | ||
645 | chalk_ir::VariableKind::Ty(tk), | ||
646 | chalk_ir::UniverseIndex::ROOT, | ||
647 | ) | ||
648 | }); | ||
649 | let value = self.value.to_chalk(db); | 541 | let value = self.value.to_chalk(db); |
650 | chalk_ir::Canonical { | 542 | chalk_ir::Canonical { |
651 | value, | 543 | value, |
@@ -658,17 +550,13 @@ where | |||
658 | .binders | 550 | .binders |
659 | .iter(&Interner) | 551 | .iter(&Interner) |
660 | .map(|k| match k.kind { | 552 | .map(|k| match k.kind { |
661 | chalk_ir::VariableKind::Ty(tk) => match tk { | 553 | chalk_ir::VariableKind::Ty(tk) => tk, |
662 | chalk_ir::TyVariableKind::General => TyKind::General, | ||
663 | chalk_ir::TyVariableKind::Integer => TyKind::Integer, | ||
664 | chalk_ir::TyVariableKind::Float => TyKind::Float, | ||
665 | }, | ||
666 | // HACK: Chalk can sometimes return new lifetime variables. We | 554 | // HACK: Chalk can sometimes return new lifetime variables. We |
667 | // want to just skip them, but to not mess up the indices of | 555 | // want to just skip them, but to not mess up the indices of |
668 | // other variables, we'll just create a new type variable in | 556 | // other variables, we'll just create a new type variable in |
669 | // their place instead. This should not matter (we never see the | 557 | // their place instead. This should not matter (we never see the |
670 | // actual *uses* of the lifetime variable). | 558 | // actual *uses* of the lifetime variable). |
671 | chalk_ir::VariableKind::Lifetime => TyKind::General, | 559 | chalk_ir::VariableKind::Lifetime => chalk_ir::TyVariableKind::General, |
672 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), | 560 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), |
673 | }) | 561 | }) |
674 | .collect(); | 562 | .collect(); |