diff options
131 files changed, 5037 insertions, 2297 deletions
diff --git a/.cargo/config b/.cargo/config index f6b0b66bf..1447614b7 100644 --- a/.cargo/config +++ b/.cargo/config | |||
@@ -3,6 +3,7 @@ xtask = "run --package xtask --bin xtask --" | |||
3 | install-ra = "run --package xtask --bin xtask -- install" # for backwards compat | 3 | install-ra = "run --package xtask --bin xtask -- install" # for backwards compat |
4 | tq = "test -- -q" | 4 | tq = "test -- -q" |
5 | qt = "tq" | 5 | qt = "tq" |
6 | lint = "clippy --all-targets -- -Aclippy::collapsible_if -Aclippy::needless_pass_by_value -Aclippy::nonminimal_bool -Aclippy::redundant_pattern_matching --cap-lints warn" | ||
6 | 7 | ||
7 | [target.x86_64-pc-windows-msvc] | 8 | [target.x86_64-pc-windows-msvc] |
8 | linker = "rust-lld" | 9 | linker = "rust-lld" |
diff --git a/Cargo.lock b/Cargo.lock index b1fef2e80..b2d009e38 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -486,6 +486,7 @@ dependencies = [ | |||
486 | "log", | 486 | "log", |
487 | "profile", | 487 | "profile", |
488 | "rustc-hash", | 488 | "rustc-hash", |
489 | "smallvec", | ||
489 | "stdx", | 490 | "stdx", |
490 | "syntax", | 491 | "syntax", |
491 | "tt", | 492 | "tt", |
diff --git a/crates/cfg/src/cfg_expr.rs b/crates/cfg/src/cfg_expr.rs index 42327f1e1..069fc01d0 100644 --- a/crates/cfg/src/cfg_expr.rs +++ b/crates/cfg/src/cfg_expr.rs | |||
@@ -49,7 +49,7 @@ impl fmt::Display for CfgAtom { | |||
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | #[derive(Debug, Clone, PartialEq, Eq)] | 52 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
53 | pub enum CfgExpr { | 53 | pub enum CfgExpr { |
54 | Invalid, | 54 | Invalid, |
55 | Atom(CfgAtom), | 55 | Atom(CfgAtom), |
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml index d4ea7327e..55e9c3f0c 100644 --- a/crates/hir/Cargo.toml +++ b/crates/hir/Cargo.toml | |||
@@ -15,6 +15,7 @@ rustc-hash = "1.1.0" | |||
15 | either = "1.5.3" | 15 | either = "1.5.3" |
16 | arrayvec = "0.5.1" | 16 | arrayvec = "0.5.1" |
17 | itertools = "0.10.0" | 17 | itertools = "0.10.0" |
18 | smallvec = "1.4.0" | ||
18 | 19 | ||
19 | stdx = { path = "../stdx", version = "0.0.0" } | 20 | stdx = { path = "../stdx", version = "0.0.0" } |
20 | syntax = { path = "../syntax", version = "0.0.0" } | 21 | syntax = { path = "../syntax", version = "0.0.0" } |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 58adc8fd3..c5161dadd 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -51,11 +51,12 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | |||
51 | use hir_ty::{ | 51 | use hir_ty::{ |
52 | autoderef, | 52 | autoderef, |
53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | 53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, |
54 | method_resolution, | 54 | method_resolution::{self, TyFingerprint}, |
55 | to_assoc_type_id, | ||
55 | traits::{FnTrait, Solution, SolutionVariables}, | 56 | traits::{FnTrait, Solution, SolutionVariables}, |
56 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 57 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
57 | InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, | 58 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, |
58 | Ty, TyDefId, TyVariableKind, | 59 | TyDefId, TyKind, TyVariableKind, |
59 | }; | 60 | }; |
60 | use rustc_hash::FxHashSet; | 61 | use rustc_hash::FxHashSet; |
61 | use stdx::{format_to, impl_from}; | 62 | use stdx::{format_to, impl_from}; |
@@ -266,8 +267,7 @@ impl ModuleDef { | |||
266 | } | 267 | } |
267 | 268 | ||
268 | pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> { | 269 | pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> { |
269 | let mut segments = Vec::new(); | 270 | let mut segments = vec![self.name(db)?.to_string()]; |
270 | segments.push(self.name(db)?.to_string()); | ||
271 | for m in self.module(db)?.path_to_root(db) { | 271 | for m in self.module(db)?.path_to_root(db) { |
272 | segments.extend(m.name(db).map(|it| it.to_string())) | 272 | segments.extend(m.name(db).map(|it| it.to_string())) |
273 | } | 273 | } |
@@ -677,7 +677,7 @@ impl_from!(Struct, Union, Enum for Adt); | |||
677 | impl Adt { | 677 | impl Adt { |
678 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 678 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
679 | let subst = db.generic_defaults(self.into()); | 679 | let subst = db.generic_defaults(self.into()); |
680 | subst.iter().any(|ty| &ty.value == &Ty::Unknown) | 680 | subst.iter().any(|ty| ty.value.is_unknown()) |
681 | } | 681 | } |
682 | 682 | ||
683 | /// Turns this ADT into a type. Any type parameters of the ADT will be | 683 | /// Turns this ADT into a type. Any type parameters of the ADT will be |
@@ -696,8 +696,8 @@ impl Adt { | |||
696 | } | 696 | } |
697 | } | 697 | } |
698 | 698 | ||
699 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | 699 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
700 | Some(self.module(db).krate()) | 700 | self.module(db).krate() |
701 | } | 701 | } |
702 | 702 | ||
703 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 703 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
@@ -802,7 +802,7 @@ impl Function { | |||
802 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); | 802 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); |
803 | let ret_type = &db.function_data(self.id).ret_type; | 803 | let ret_type = &db.function_data(self.id).ret_type; |
804 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 804 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
805 | let ty = Ty::from_hir_ext(&ctx, ret_type).0; | 805 | let ty = ctx.lower_ty(ret_type); |
806 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 806 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
807 | } | 807 | } |
808 | 808 | ||
@@ -817,7 +817,7 @@ impl Function { | |||
817 | let resolver = self.id.resolver(db.upcast()); | 817 | let resolver = self.id.resolver(db.upcast()); |
818 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); | 818 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); |
819 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 819 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
820 | let environment = TraitEnvironment::lower(db, &resolver); | 820 | let environment = db.trait_environment(self.id.into()); |
821 | db.function_data(self.id) | 821 | db.function_data(self.id) |
822 | .params | 822 | .params |
823 | .iter() | 823 | .iter() |
@@ -825,7 +825,7 @@ impl Function { | |||
825 | let ty = Type { | 825 | let ty = Type { |
826 | krate, | 826 | krate, |
827 | ty: InEnvironment { | 827 | ty: InEnvironment { |
828 | value: Ty::from_hir_ext(&ctx, type_ref).0, | 828 | value: ctx.lower_ty(type_ref), |
829 | environment: environment.clone(), | 829 | environment: environment.clone(), |
830 | }, | 830 | }, |
831 | }; | 831 | }; |
@@ -1012,15 +1012,15 @@ pub struct TypeAlias { | |||
1012 | impl TypeAlias { | 1012 | impl TypeAlias { |
1013 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 1013 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
1014 | let subst = db.generic_defaults(self.id.into()); | 1014 | let subst = db.generic_defaults(self.id.into()); |
1015 | subst.iter().any(|ty| &ty.value == &Ty::Unknown) | 1015 | subst.iter().any(|ty| ty.value.is_unknown()) |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 1018 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
1019 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } | 1019 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | 1022 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
1023 | Some(self.module(db).krate()) | 1023 | self.module(db).krate() |
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1026 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
@@ -1384,7 +1384,7 @@ impl TypeParam { | |||
1384 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | 1384 | pub fn ty(self, db: &dyn HirDatabase) -> Type { |
1385 | let resolver = self.id.parent.resolver(db.upcast()); | 1385 | let resolver = self.id.parent.resolver(db.upcast()); |
1386 | let krate = self.id.parent.module(db.upcast()).krate(); | 1386 | let krate = self.id.parent.module(db.upcast()).krate(); |
1387 | let ty = Ty::Placeholder(self.id); | 1387 | let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id)).intern(&Interner); |
1388 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1388 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1389 | } | 1389 | } |
1390 | 1390 | ||
@@ -1483,9 +1483,44 @@ impl Impl { | |||
1483 | 1483 | ||
1484 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() | 1484 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() |
1485 | } | 1485 | } |
1486 | pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { | 1486 | |
1487 | let impls = db.trait_impls_in_crate(krate.id); | 1487 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { |
1488 | impls.for_trait(trait_.id).map(Self::from).collect() | 1488 | let def_crates = match ty.value.def_crates(db, krate) { |
1489 | Some(def_crates) => def_crates, | ||
1490 | None => return Vec::new(), | ||
1491 | }; | ||
1492 | |||
1493 | let filter = |impl_def: &Impl| { | ||
1494 | let target_ty = impl_def.target_ty(db); | ||
1495 | let rref = target_ty.remove_ref(); | ||
1496 | ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) | ||
1497 | }; | ||
1498 | |||
1499 | let mut all = Vec::new(); | ||
1500 | def_crates.into_iter().for_each(|id| { | ||
1501 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | ||
1502 | }); | ||
1503 | let fp = TyFingerprint::for_impl(&ty.value); | ||
1504 | for id in db.crate_graph().iter() { | ||
1505 | match fp { | ||
1506 | Some(fp) => all.extend( | ||
1507 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), | ||
1508 | ), | ||
1509 | None => all | ||
1510 | .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)), | ||
1511 | } | ||
1512 | } | ||
1513 | all | ||
1514 | } | ||
1515 | |||
1516 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { | ||
1517 | let krate = trait_.module(db).krate(); | ||
1518 | let mut all = Vec::new(); | ||
1519 | for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) { | ||
1520 | let impls = db.trait_impls_in_crate(id); | ||
1521 | all.extend(impls.for_trait(trait_.id).map(Self::from)) | ||
1522 | } | ||
1523 | all | ||
1489 | } | 1524 | } |
1490 | 1525 | ||
1491 | // FIXME: the return type is wrong. This should be a hir version of | 1526 | // FIXME: the return type is wrong. This should be a hir version of |
@@ -1499,7 +1534,7 @@ impl Impl { | |||
1499 | let resolver = self.id.resolver(db.upcast()); | 1534 | let resolver = self.id.resolver(db.upcast()); |
1500 | let krate = self.id.lookup(db.upcast()).container.krate(); | 1535 | let krate = self.id.lookup(db.upcast()).container.krate(); |
1501 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1536 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
1502 | let ty = Ty::from_hir(&ctx, &impl_data.target_type); | 1537 | let ty = ctx.lower_ty(&impl_data.target_type); |
1503 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1538 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1504 | } | 1539 | } |
1505 | 1540 | ||
@@ -1563,13 +1598,15 @@ impl Type { | |||
1563 | resolver: &Resolver, | 1598 | resolver: &Resolver, |
1564 | ty: Ty, | 1599 | ty: Ty, |
1565 | ) -> Type { | 1600 | ) -> Type { |
1566 | let environment = TraitEnvironment::lower(db, &resolver); | 1601 | let environment = |
1602 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | ||
1567 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1603 | Type { krate, ty: InEnvironment { value: ty, environment } } |
1568 | } | 1604 | } |
1569 | 1605 | ||
1570 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { | 1606 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { |
1571 | let resolver = lexical_env.resolver(db.upcast()); | 1607 | let resolver = lexical_env.resolver(db.upcast()); |
1572 | let environment = TraitEnvironment::lower(db, &resolver); | 1608 | let environment = |
1609 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | ||
1573 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1610 | Type { krate, ty: InEnvironment { value: ty, environment } } |
1574 | } | 1611 | } |
1575 | 1612 | ||
@@ -1584,25 +1621,25 @@ impl Type { | |||
1584 | } | 1621 | } |
1585 | 1622 | ||
1586 | pub fn is_unit(&self) -> bool { | 1623 | pub fn is_unit(&self) -> bool { |
1587 | matches!(self.ty.value, Ty::Tuple(0, ..)) | 1624 | matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) |
1588 | } | 1625 | } |
1589 | pub fn is_bool(&self) -> bool { | 1626 | pub fn is_bool(&self) -> bool { |
1590 | matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) | 1627 | matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) |
1591 | } | 1628 | } |
1592 | 1629 | ||
1593 | pub fn is_mutable_reference(&self) -> bool { | 1630 | pub fn is_mutable_reference(&self) -> bool { |
1594 | matches!(self.ty.value, Ty::Ref(hir_ty::Mutability::Mut, ..)) | 1631 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1595 | } | 1632 | } |
1596 | 1633 | ||
1597 | pub fn remove_ref(&self) -> Option<Type> { | 1634 | pub fn remove_ref(&self) -> Option<Type> { |
1598 | match &self.ty.value { | 1635 | match &self.ty.value.interned(&Interner) { |
1599 | Ty::Ref(.., substs) => Some(self.derived(substs[0].clone())), | 1636 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
1600 | _ => None, | 1637 | _ => None, |
1601 | } | 1638 | } |
1602 | } | 1639 | } |
1603 | 1640 | ||
1604 | pub fn is_unknown(&self) -> bool { | 1641 | pub fn is_unknown(&self) -> bool { |
1605 | matches!(self.ty.value, Ty::Unknown) | 1642 | self.ty.value.is_unknown() |
1606 | } | 1643 | } |
1607 | 1644 | ||
1608 | /// Checks that particular type `ty` implements `std::future::Future`. | 1645 | /// Checks that particular type `ty` implements `std::future::Future`. |
@@ -1683,8 +1720,11 @@ impl Type { | |||
1683 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1720 | .fill(args.iter().map(|t| t.ty.value.clone())) |
1684 | .build(); | 1721 | .build(); |
1685 | let predicate = ProjectionPredicate { | 1722 | let predicate = ProjectionPredicate { |
1686 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, | 1723 | projection_ty: ProjectionTy { |
1687 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), | 1724 | associated_ty_id: to_assoc_type_id(alias.id), |
1725 | substitution: subst, | ||
1726 | }, | ||
1727 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner), | ||
1688 | }; | 1728 | }; |
1689 | let goal = Canonical { | 1729 | let goal = Canonical { |
1690 | value: InEnvironment::new( | 1730 | value: InEnvironment::new( |
@@ -1712,26 +1752,23 @@ impl Type { | |||
1712 | } | 1752 | } |
1713 | 1753 | ||
1714 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1754 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1715 | let def = match self.ty.value { | 1755 | let def = self.ty.value.callable_def(db); |
1716 | Ty::FnDef(def, _) => Some(def), | ||
1717 | _ => None, | ||
1718 | }; | ||
1719 | 1756 | ||
1720 | let sig = self.ty.value.callable_sig(db)?; | 1757 | let sig = self.ty.value.callable_sig(db)?; |
1721 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) | 1758 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) |
1722 | } | 1759 | } |
1723 | 1760 | ||
1724 | pub fn is_closure(&self) -> bool { | 1761 | pub fn is_closure(&self) -> bool { |
1725 | matches!(&self.ty.value, Ty::Closure { .. }) | 1762 | matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) |
1726 | } | 1763 | } |
1727 | 1764 | ||
1728 | pub fn is_fn(&self) -> bool { | 1765 | pub fn is_fn(&self) -> bool { |
1729 | matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) | 1766 | matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) |
1730 | } | 1767 | } |
1731 | 1768 | ||
1732 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1769 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1733 | let adt_id = match self.ty.value { | 1770 | let adt_id = match self.ty.value.interned(&Interner) { |
1734 | Ty::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, | 1771 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, |
1735 | _ => return false, | 1772 | _ => return false, |
1736 | }; | 1773 | }; |
1737 | 1774 | ||
@@ -1743,24 +1780,45 @@ impl Type { | |||
1743 | } | 1780 | } |
1744 | 1781 | ||
1745 | pub fn is_raw_ptr(&self) -> bool { | 1782 | pub fn is_raw_ptr(&self) -> bool { |
1746 | matches!(&self.ty.value, Ty::Raw(..)) | 1783 | matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) |
1747 | } | 1784 | } |
1748 | 1785 | ||
1749 | pub fn contains_unknown(&self) -> bool { | 1786 | pub fn contains_unknown(&self) -> bool { |
1750 | return go(&self.ty.value); | 1787 | return go(&self.ty.value); |
1751 | 1788 | ||
1752 | fn go(ty: &Ty) -> bool { | 1789 | fn go(ty: &Ty) -> bool { |
1753 | match ty { | 1790 | match ty.interned(&Interner) { |
1754 | Ty::Unknown => true, | 1791 | TyKind::Unknown => true, |
1755 | _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), | 1792 | |
1793 | TyKind::Adt(_, substs) | ||
1794 | | TyKind::AssociatedType(_, substs) | ||
1795 | | TyKind::Tuple(_, substs) | ||
1796 | | TyKind::OpaqueType(_, substs) | ||
1797 | | TyKind::FnDef(_, substs) | ||
1798 | | TyKind::Closure(_, substs) => substs.iter().any(go), | ||
1799 | |||
1800 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { | ||
1801 | go(ty) | ||
1802 | } | ||
1803 | |||
1804 | TyKind::Scalar(_) | ||
1805 | | TyKind::Str | ||
1806 | | TyKind::Never | ||
1807 | | TyKind::Placeholder(_) | ||
1808 | | TyKind::BoundVar(_) | ||
1809 | | TyKind::InferenceVar(_, _) | ||
1810 | | TyKind::Dyn(_) | ||
1811 | | TyKind::Function(_) | ||
1812 | | TyKind::Alias(_) | ||
1813 | | TyKind::ForeignType(_) => false, | ||
1756 | } | 1814 | } |
1757 | } | 1815 | } |
1758 | } | 1816 | } |
1759 | 1817 | ||
1760 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1818 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1761 | let (variant_id, substs) = match self.ty.value { | 1819 | let (variant_id, substs) = match self.ty.value.interned(&Interner) { |
1762 | Ty::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), | 1820 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), |
1763 | Ty::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), | 1821 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), |
1764 | _ => return Vec::new(), | 1822 | _ => return Vec::new(), |
1765 | }; | 1823 | }; |
1766 | 1824 | ||
@@ -1775,7 +1833,7 @@ impl Type { | |||
1775 | } | 1833 | } |
1776 | 1834 | ||
1777 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1835 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1778 | if let Ty::Tuple(_, substs) = &self.ty.value { | 1836 | if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { |
1779 | substs.iter().map(|ty| self.derived(ty.clone())).collect() | 1837 | substs.iter().map(|ty| self.derived(ty.clone())).collect() |
1780 | } else { | 1838 | } else { |
1781 | Vec::new() | 1839 | Vec::new() |
@@ -1910,12 +1968,6 @@ impl Type { | |||
1910 | self.ty.value.associated_type_parent_trait(db).map(Into::into) | 1968 | self.ty.value.associated_type_parent_trait(db).map(Into::into) |
1911 | } | 1969 | } |
1912 | 1970 | ||
1913 | // FIXME: provide required accessors such that it becomes implementable from outside. | ||
1914 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | ||
1915 | let rref = other.remove_ref(); | ||
1916 | self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value)) | ||
1917 | } | ||
1918 | |||
1919 | fn derived(&self, ty: Ty) -> Type { | 1971 | fn derived(&self, ty: Ty) -> Type { |
1920 | Type { | 1972 | Type { |
1921 | krate: self.krate, | 1973 | krate: self.krate, |
@@ -1957,36 +2009,40 @@ impl Type { | |||
1957 | 2009 | ||
1958 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2010 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
1959 | let ty = type_.ty.value.strip_references(); | 2011 | let ty = type_.ty.value.strip_references(); |
1960 | match ty { | 2012 | match ty.interned(&Interner) { |
1961 | Ty::Adt(..) => { | 2013 | TyKind::Adt(..) => { |
1962 | cb(type_.derived(ty.clone())); | 2014 | cb(type_.derived(ty.clone())); |
1963 | } | 2015 | } |
1964 | Ty::AssociatedType(..) => { | 2016 | TyKind::AssociatedType(..) => { |
1965 | if let Some(_) = ty.associated_type_parent_trait(db) { | 2017 | if let Some(_) = ty.associated_type_parent_trait(db) { |
1966 | cb(type_.derived(ty.clone())); | 2018 | cb(type_.derived(ty.clone())); |
1967 | } | 2019 | } |
1968 | } | 2020 | } |
1969 | Ty::OpaqueType(..) => { | 2021 | TyKind::OpaqueType(..) => { |
1970 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2022 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1971 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2023 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1972 | } | 2024 | } |
1973 | } | 2025 | } |
1974 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 2026 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
1975 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2027 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1976 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2028 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1977 | } | 2029 | } |
1978 | 2030 | ||
1979 | walk_substs(db, type_, &opaque_ty.parameters, cb); | 2031 | walk_substs(db, type_, &opaque_ty.substitution, cb); |
1980 | } | 2032 | } |
1981 | Ty::Placeholder(_) => { | 2033 | TyKind::Placeholder(_) => { |
1982 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2034 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1983 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2035 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1984 | } | 2036 | } |
1985 | } | 2037 | } |
1986 | Ty::Dyn(bounds) => { | 2038 | TyKind::Dyn(bounds) => { |
1987 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); | 2039 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); |
1988 | } | 2040 | } |
1989 | 2041 | ||
2042 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { | ||
2043 | walk_type(db, &type_.derived(ty.clone()), cb); | ||
2044 | } | ||
2045 | |||
1990 | _ => {} | 2046 | _ => {} |
1991 | } | 2047 | } |
1992 | if let Some(substs) = ty.substs() { | 2048 | if let Some(substs) = ty.substs() { |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 945638cc5..519339c0c 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -259,6 +259,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
259 | } | 259 | } |
260 | 260 | ||
261 | pub fn to_module_def(&self, file: FileId) -> Option<Module> { | 261 | pub fn to_module_def(&self, file: FileId) -> Option<Module> { |
262 | self.imp.to_module_def(file).next() | ||
263 | } | ||
264 | |||
265 | pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> { | ||
262 | self.imp.to_module_def(file) | 266 | self.imp.to_module_def(file) |
263 | } | 267 | } |
264 | 268 | ||
@@ -537,8 +541,8 @@ impl<'db> SemanticsImpl<'db> { | |||
537 | f(&mut ctx) | 541 | f(&mut ctx) |
538 | } | 542 | } |
539 | 543 | ||
540 | fn to_module_def(&self, file: FileId) -> Option<Module> { | 544 | fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> { |
541 | self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) | 545 | self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from) |
542 | } | 546 | } |
543 | 547 | ||
544 | fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { | 548 | fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 6c612ee86..e9d820140 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -12,6 +12,7 @@ use hir_def::{ | |||
12 | }; | 12 | }; |
13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; | 13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; |
14 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
15 | use smallvec::SmallVec; | ||
15 | use stdx::impl_from; | 16 | use stdx::impl_from; |
16 | use syntax::{ | 17 | use syntax::{ |
17 | ast::{self, NameOwner}, | 18 | ast::{self, NameOwner}, |
@@ -28,14 +29,19 @@ pub(super) struct SourceToDefCtx<'a, 'b> { | |||
28 | } | 29 | } |
29 | 30 | ||
30 | impl SourceToDefCtx<'_, '_> { | 31 | impl SourceToDefCtx<'_, '_> { |
31 | pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> { | 32 | pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> { |
32 | let _p = profile::span("SourceBinder::to_module_def"); | 33 | let _p = profile::span("SourceBinder::to_module_def"); |
33 | self.db.relevant_crates(file).iter().find_map(|&crate_id| { | 34 | let mut mods = SmallVec::new(); |
35 | for &crate_id in self.db.relevant_crates(file).iter() { | ||
34 | // FIXME: inner items | 36 | // FIXME: inner items |
35 | let crate_def_map = self.db.crate_def_map(crate_id); | 37 | let crate_def_map = self.db.crate_def_map(crate_id); |
36 | let local_id = crate_def_map.modules_for_file(file).next()?; | 38 | mods.extend( |
37 | Some(crate_def_map.module_id(local_id)) | 39 | crate_def_map |
38 | }) | 40 | .modules_for_file(file) |
41 | .map(|local_id| crate_def_map.module_id(local_id)), | ||
42 | ) | ||
43 | } | ||
44 | mods | ||
39 | } | 45 | } |
40 | 46 | ||
41 | pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { | 47 | pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { |
@@ -55,7 +61,7 @@ impl SourceToDefCtx<'_, '_> { | |||
55 | Some(parent_declaration) => self.module_to_def(parent_declaration), | 61 | Some(parent_declaration) => self.module_to_def(parent_declaration), |
56 | None => { | 62 | None => { |
57 | let file_id = src.file_id.original_file(self.db.upcast()); | 63 | let file_id = src.file_id.original_file(self.db.upcast()); |
58 | self.file_to_def(file_id) | 64 | self.file_to_def(file_id).get(0).copied() |
59 | } | 65 | } |
60 | }?; | 66 | }?; |
61 | 67 | ||
@@ -185,7 +191,7 @@ impl SourceToDefCtx<'_, '_> { | |||
185 | ) -> Option<MacroDefId> { | 191 | ) -> Option<MacroDefId> { |
186 | let kind = MacroDefKind::Declarative; | 192 | let kind = MacroDefKind::Declarative; |
187 | let file_id = src.file_id.original_file(self.db.upcast()); | 193 | let file_id = src.file_id.original_file(self.db.upcast()); |
188 | let krate = self.file_to_def(file_id)?.krate(); | 194 | let krate = self.file_to_def(file_id).get(0).copied()?.krate(); |
189 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); | 195 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); |
190 | let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast())); | 196 | let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast())); |
191 | Some(MacroDefId { krate, ast_id, kind, local_inner: false }) | 197 | Some(MacroDefId { krate, ast_id, kind, local_inner: false }) |
@@ -245,7 +251,7 @@ impl SourceToDefCtx<'_, '_> { | |||
245 | return Some(res); | 251 | return Some(res); |
246 | } | 252 | } |
247 | 253 | ||
248 | let def = self.file_to_def(src.file_id.original_file(self.db.upcast()))?; | 254 | let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?; |
249 | Some(def.into()) | 255 | Some(def.into()) |
250 | } | 256 | } |
251 | 257 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index d546512cb..4d59293e9 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -161,8 +161,9 @@ impl SourceAnalyzer { | |||
161 | db: &dyn HirDatabase, | 161 | db: &dyn HirDatabase, |
162 | field: &ast::RecordExprField, | 162 | field: &ast::RecordExprField, |
163 | ) -> Option<(Field, Option<Local>)> { | 163 | ) -> Option<(Field, Option<Local>)> { |
164 | let expr = field.expr()?; | 164 | let expr_id = |
165 | let expr_id = self.expr_id(db, &expr)?; | 165 | self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?; |
166 | |||
166 | let local = if field.name_ref().is_some() { | 167 | let local = if field.name_ref().is_some() { |
167 | None | 168 | None |
168 | } else { | 169 | } else { |
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml index c2d99280f..475d337f3 100644 --- a/crates/hir_def/Cargo.toml +++ b/crates/hir_def/Cargo.toml | |||
@@ -10,7 +10,7 @@ edition = "2018" | |||
10 | doctest = false | 10 | doctest = false |
11 | 11 | ||
12 | [dependencies] | 12 | [dependencies] |
13 | cov-mark = "1.1" | 13 | cov-mark = { version = "1.1", features = ["thread-local"] } |
14 | log = "0.4.8" | 14 | log = "0.4.8" |
15 | once_cell = "1.3.1" | 15 | once_cell = "1.3.1" |
16 | rustc-hash = "1.1.0" | 16 | rustc-hash = "1.1.0" |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 97cdbbb9e..7b41b148c 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -9,6 +9,7 @@ use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; | |||
9 | use itertools::Itertools; | 9 | use itertools::Itertools; |
10 | use la_arena::ArenaMap; | 10 | use la_arena::ArenaMap; |
11 | use mbe::ast_to_token_tree; | 11 | use mbe::ast_to_token_tree; |
12 | use smallvec::{smallvec, SmallVec}; | ||
12 | use syntax::{ | 13 | use syntax::{ |
13 | ast::{self, AstNode, AttrsOwner}, | 14 | ast::{self, AstNode, AttrsOwner}, |
14 | match_ast, AstToken, SmolStr, SyntaxNode, | 15 | match_ast, AstToken, SmolStr, SyntaxNode, |
@@ -134,53 +135,42 @@ impl RawAttrs { | |||
134 | let crate_graph = db.crate_graph(); | 135 | let crate_graph = db.crate_graph(); |
135 | let new_attrs = self | 136 | let new_attrs = self |
136 | .iter() | 137 | .iter() |
137 | .filter_map(|attr| { | 138 | .flat_map(|attr| -> SmallVec<[_; 1]> { |
138 | let attr = attr.clone(); | 139 | let attr = attr.clone(); |
139 | let is_cfg_attr = | 140 | let is_cfg_attr = |
140 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); | 141 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); |
141 | if !is_cfg_attr { | 142 | if !is_cfg_attr { |
142 | return Some(attr); | 143 | return smallvec![attr]; |
143 | } | 144 | } |
144 | 145 | ||
145 | let subtree = match &attr.input { | 146 | let subtree = match &attr.input { |
146 | Some(AttrInput::TokenTree(it)) => it, | 147 | Some(AttrInput::TokenTree(it)) => it, |
147 | _ => return Some(attr), | 148 | _ => return smallvec![attr], |
148 | }; | 149 | }; |
149 | 150 | ||
150 | // Input subtree is: `(cfg, attr)` | 151 | // Input subtree is: `(cfg, $(attr),+)` |
151 | // Split it up into a `cfg` and an `attr` subtree. | 152 | // Split it up into a `cfg` subtree and the `attr` subtrees. |
152 | // FIXME: There should be a common API for this. | 153 | // FIXME: There should be a common API for this. |
153 | let mut saw_comma = false; | 154 | let mut parts = subtree.token_trees.split( |
154 | let (mut cfg, attr): (Vec<_>, Vec<_>) = | 155 | |tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ','), |
155 | subtree.clone().token_trees.into_iter().partition(|tree| { | 156 | ); |
156 | if saw_comma { | 157 | let cfg = parts.next().unwrap(); |
157 | return false; | 158 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; |
158 | } | ||
159 | |||
160 | match tree { | ||
161 | tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { | ||
162 | saw_comma = true; | ||
163 | } | ||
164 | _ => {} | ||
165 | } | ||
166 | |||
167 | true | ||
168 | }); | ||
169 | cfg.pop(); // `,` ends up in here | ||
170 | |||
171 | let attr = Subtree { delimiter: None, token_trees: attr }; | ||
172 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg }; | ||
173 | let cfg = CfgExpr::parse(&cfg); | 159 | let cfg = CfgExpr::parse(&cfg); |
160 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { | ||
161 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; | ||
162 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; | ||
163 | let hygiene = Hygiene::new_unhygienic(); // FIXME | ||
164 | Attr::from_src(attr, &hygiene) | ||
165 | }); | ||
174 | 166 | ||
175 | let cfg_options = &crate_graph[krate].cfg_options; | 167 | let cfg_options = &crate_graph[krate].cfg_options; |
176 | if cfg_options.check(&cfg) == Some(false) { | 168 | if cfg_options.check(&cfg) == Some(false) { |
177 | None | 169 | smallvec![] |
178 | } else { | 170 | } else { |
179 | cov_mark::hit!(cfg_attr_active); | 171 | cov_mark::hit!(cfg_attr_active); |
180 | 172 | ||
181 | let attr = ast::Attr::parse(&format!("#[{}]", attr)).ok()?; | 173 | attrs.collect() |
182 | let hygiene = Hygiene::new_unhygienic(); // FIXME | ||
183 | Attr::from_src(attr, &hygiene) | ||
184 | } | 174 | } |
185 | }) | 175 | }) |
186 | .collect(); | 176 | .collect(); |
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 19c4eb521..8bcc350ce 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -253,11 +253,18 @@ pub type LabelSource = InFile<LabelPtr>; | |||
253 | pub struct BodySourceMap { | 253 | pub struct BodySourceMap { |
254 | expr_map: FxHashMap<ExprSource, ExprId>, | 254 | expr_map: FxHashMap<ExprSource, ExprId>, |
255 | expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>, | 255 | expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>, |
256 | |||
256 | pat_map: FxHashMap<PatSource, PatId>, | 257 | pat_map: FxHashMap<PatSource, PatId>, |
257 | pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, | 258 | pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, |
259 | |||
258 | label_map: FxHashMap<LabelSource, LabelId>, | 260 | label_map: FxHashMap<LabelSource, LabelId>, |
259 | label_map_back: ArenaMap<LabelId, LabelSource>, | 261 | label_map_back: ArenaMap<LabelId, LabelSource>, |
260 | field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, | 262 | |
263 | /// We don't create explicit nodes for record fields (`S { record_field: 92 }`). | ||
264 | /// Instead, we use id of expression (`92`) to identify the field. | ||
265 | field_map: FxHashMap<InFile<AstPtr<ast::RecordExprField>>, ExprId>, | ||
266 | field_map_back: FxHashMap<ExprId, InFile<AstPtr<ast::RecordExprField>>>, | ||
267 | |||
261 | expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, | 268 | expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, |
262 | 269 | ||
263 | /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in | 270 | /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in |
@@ -337,6 +344,8 @@ impl Index<LabelId> for Body { | |||
337 | } | 344 | } |
338 | } | 345 | } |
339 | 346 | ||
347 | // FIXME: Change `node_` prefix to something more reasonable. | ||
348 | // Perhaps `expr_syntax` and `expr_id`? | ||
340 | impl BodySourceMap { | 349 | impl BodySourceMap { |
341 | pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { | 350 | pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { |
342 | self.expr_map_back[expr].clone() | 351 | self.expr_map_back[expr].clone() |
@@ -375,8 +384,12 @@ impl BodySourceMap { | |||
375 | self.label_map.get(&src).cloned() | 384 | self.label_map.get(&src).cloned() |
376 | } | 385 | } |
377 | 386 | ||
378 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> { | 387 | pub fn field_syntax(&self, expr: ExprId) -> InFile<AstPtr<ast::RecordExprField>> { |
379 | self.field_map[&(expr, field)].clone() | 388 | self.field_map_back[&expr].clone() |
389 | } | ||
390 | pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> { | ||
391 | let src = node.map(|it| AstPtr::new(it)); | ||
392 | self.field_map.get(&src).cloned() | ||
380 | } | 393 | } |
381 | 394 | ||
382 | pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) { | 395 | pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) { |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 8c8eb8007..8934ae6c9 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -379,23 +379,22 @@ impl ExprCollector<'_> { | |||
379 | } | 379 | } |
380 | ast::Expr::RecordExpr(e) => { | 380 | ast::Expr::RecordExpr(e) => { |
381 | let path = e.path().and_then(|path| self.expander.parse_path(path)); | 381 | let path = e.path().and_then(|path| self.expander.parse_path(path)); |
382 | let mut field_ptrs = Vec::new(); | ||
383 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { | 382 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { |
384 | let fields = nfl | 383 | let fields = nfl |
385 | .fields() | 384 | .fields() |
386 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) | ||
387 | .filter_map(|field| { | 385 | .filter_map(|field| { |
388 | self.check_cfg(&field)?; | 386 | self.check_cfg(&field)?; |
389 | 387 | ||
390 | let name = field.field_name()?.as_name(); | 388 | let name = field.field_name()?.as_name(); |
391 | 389 | ||
392 | Some(RecordLitField { | 390 | let expr = match field.expr() { |
393 | name, | 391 | Some(e) => self.collect_expr(e), |
394 | expr: match field.expr() { | 392 | None => self.missing_expr(), |
395 | Some(e) => self.collect_expr(e), | 393 | }; |
396 | None => self.missing_expr(), | 394 | let src = self.expander.to_source(AstPtr::new(&field)); |
397 | }, | 395 | self.source_map.field_map.insert(src.clone(), expr); |
398 | }) | 396 | self.source_map.field_map_back.insert(expr, src); |
397 | Some(RecordLitField { name, expr }) | ||
399 | }) | 398 | }) |
400 | .collect(); | 399 | .collect(); |
401 | let spread = nfl.spread().map(|s| self.collect_expr(s)); | 400 | let spread = nfl.spread().map(|s| self.collect_expr(s)); |
@@ -404,12 +403,7 @@ impl ExprCollector<'_> { | |||
404 | Expr::RecordLit { path, fields: Vec::new(), spread: None } | 403 | Expr::RecordLit { path, fields: Vec::new(), spread: None } |
405 | }; | 404 | }; |
406 | 405 | ||
407 | let res = self.alloc_expr(record_lit, syntax_ptr); | 406 | self.alloc_expr(record_lit, syntax_ptr) |
408 | for (i, ptr) in field_ptrs.into_iter().enumerate() { | ||
409 | let src = self.expander.to_source(ptr); | ||
410 | self.source_map.field_map.insert((res, i), src); | ||
411 | } | ||
412 | res | ||
413 | } | 407 | } |
414 | ast::Expr::FieldExpr(e) => { | 408 | ast::Expr::FieldExpr(e) => { |
415 | let expr = self.collect_expr_opt(e.expr()); | 409 | let expr = self.collect_expr_opt(e.expr()); |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 6bb334573..09bcb10dc 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -209,18 +209,6 @@ impl ItemTree { | |||
209 | } | 209 | } |
210 | } | 210 | } |
211 | 211 | ||
212 | pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source { | ||
213 | // This unwrap cannot fail, since it has either succeeded above, or resulted in an empty | ||
214 | // ItemTree (in which case there is no valid `FileItemTreeId` to call this method with). | ||
215 | let root = | ||
216 | db.parse_or_expand(of.file_id).expect("parse_or_expand failed on constructed ItemTree"); | ||
217 | |||
218 | let id = self[of.value].ast_id(); | ||
219 | let map = db.ast_id_map(of.file_id); | ||
220 | let ptr = map.get(id); | ||
221 | ptr.to_node(&root) | ||
222 | } | ||
223 | |||
224 | fn data(&self) -> &ItemTreeData { | 212 | fn data(&self) -> &ItemTreeData { |
225 | self.data.as_ref().expect("attempted to access data of empty ItemTree") | 213 | self.data.as_ref().expect("attempted to access data of empty ItemTree") |
226 | } | 214 | } |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 6d11c5be4..c6655c5fb 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -341,6 +341,16 @@ pub enum DefWithBodyId { | |||
341 | 341 | ||
342 | impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); | 342 | impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); |
343 | 343 | ||
344 | impl DefWithBodyId { | ||
345 | pub fn as_generic_def_id(self) -> Option<GenericDefId> { | ||
346 | match self { | ||
347 | DefWithBodyId::FunctionId(f) => Some(f.into()), | ||
348 | DefWithBodyId::StaticId(_) => None, | ||
349 | DefWithBodyId::ConstId(c) => Some(c.into()), | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
344 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 354 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
345 | pub enum AssocItemId { | 355 | pub enum AssocItemId { |
346 | FunctionId(FunctionId), | 356 | FunctionId(FunctionId), |
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index bfc1ab13f..c22ef46fd 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -149,6 +149,9 @@ fn inactive_via_cfg_attr() { | |||
149 | #[cfg_attr(not(never), cfg(not(no)))] fn f() {} | 149 | #[cfg_attr(not(never), cfg(not(no)))] fn f() {} |
150 | 150 | ||
151 | #[cfg_attr(never, cfg(no))] fn g() {} | 151 | #[cfg_attr(never, cfg(no))] fn g() {} |
152 | |||
153 | #[cfg_attr(not(never), inline, cfg(no))] fn h() {} | ||
154 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: no is disabled | ||
152 | "#, | 155 | "#, |
153 | ); | 156 | ); |
154 | } | 157 | } |
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs index eda982c85..10977761c 100644 --- a/crates/hir_def/src/test_db.rs +++ b/crates/hir_def/src/test_db.rs | |||
@@ -15,7 +15,7 @@ use rustc_hash::FxHashSet; | |||
15 | use syntax::{algo, ast, AstNode, TextRange, TextSize}; | 15 | use syntax::{algo, ast, AstNode, TextRange, TextSize}; |
16 | use test_utils::extract_annotations; | 16 | use test_utils::extract_annotations; |
17 | 17 | ||
18 | use crate::{db::DefDatabase, nameres::DefMap, Lookup, ModuleDefId, ModuleId}; | 18 | use crate::{db::DefDatabase, nameres::DefMap, src::HasSource, Lookup, ModuleDefId, ModuleId}; |
19 | 19 | ||
20 | #[salsa::database( | 20 | #[salsa::database( |
21 | base_db::SourceDatabaseExtStorage, | 21 | base_db::SourceDatabaseExtStorage, |
@@ -115,14 +115,9 @@ impl TestDB { | |||
115 | if file_id != position.file_id.into() { | 115 | if file_id != position.file_id.into() { |
116 | continue; | 116 | continue; |
117 | } | 117 | } |
118 | let root = self.parse_or_expand(file_id).unwrap(); | ||
119 | let ast_map = self.ast_id_map(file_id); | ||
120 | let item_tree = self.item_tree(file_id); | ||
121 | for decl in module.scope.declarations() { | 118 | for decl in module.scope.declarations() { |
122 | if let ModuleDefId::FunctionId(it) = decl { | 119 | if let ModuleDefId::FunctionId(it) = decl { |
123 | let ast = | 120 | let range = it.lookup(self).source(self).value.syntax().text_range(); |
124 | ast_map.get(item_tree[it.lookup(self).id.value].ast_id).to_node(&root); | ||
125 | let range = ast.syntax().text_range(); | ||
126 | 121 | ||
127 | if !range.contains(position.offset) { | 122 | if !range.contains(position.offset) { |
128 | continue; | 123 | continue; |
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs index dfdb9cf59..5e908b223 100644 --- a/crates/hir_expand/src/builtin_derive.rs +++ b/crates/hir_expand/src/builtin_derive.rs | |||
@@ -108,7 +108,7 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, mbe::ExpandError> { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | fn make_type_args(n: usize, bound: Vec<tt::TokenTree>) -> Vec<tt::TokenTree> { | 110 | fn make_type_args(n: usize, bound: Vec<tt::TokenTree>) -> Vec<tt::TokenTree> { |
111 | let mut result = Vec::<tt::TokenTree>::new(); | 111 | let mut result = Vec::<tt::TokenTree>::with_capacity(n * 2); |
112 | result.push( | 112 | result.push( |
113 | tt::Leaf::Punct(tt::Punct { | 113 | tt::Leaf::Punct(tt::Punct { |
114 | char: '<', | 114 | char: '<', |
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index cb6e23320..9086e6c17 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -340,6 +340,8 @@ fn parse_macro_with_arg( | |||
340 | None => return ExpandResult { value: None, err: result.err }, | 340 | None => return ExpandResult { value: None, err: result.err }, |
341 | }; | 341 | }; |
342 | 342 | ||
343 | log::debug!("expanded = {}", tt.as_debug_string()); | ||
344 | |||
343 | let fragment_kind = to_fragment_kind(db, macro_call_id); | 345 | let fragment_kind = to_fragment_kind(db, macro_call_id); |
344 | 346 | ||
345 | let (parse, rev_token_map) = match mbe::token_tree_to_syntax_node(&tt, fragment_kind) { | 347 | let (parse, rev_token_map) = match mbe::token_tree_to_syntax_node(&tt, fragment_kind) { |
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index e833e032c..43de9edd6 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs | |||
@@ -191,6 +191,8 @@ pub mod known { | |||
191 | filter_map, | 191 | filter_map, |
192 | next, | 192 | next, |
193 | iter_mut, | 193 | iter_mut, |
194 | len, | ||
195 | is_empty, | ||
194 | // Builtin macros | 196 | // Builtin macros |
195 | file, | 197 | file, |
196 | column, | 198 | column, |
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index b9c93f56f..0ef27cd37 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -10,7 +10,7 @@ edition = "2018" | |||
10 | doctest = false | 10 | doctest = false |
11 | 11 | ||
12 | [dependencies] | 12 | [dependencies] |
13 | cov-mark = "1.1" | 13 | cov-mark = { version = "1.1", features = ["thread-local"] } |
14 | itertools = "0.10.0" | 14 | itertools = "0.10.0" |
15 | arrayvec = "0.5.1" | 15 | arrayvec = "0.5.1" |
16 | smallvec = "1.2.0" | 16 | smallvec = "1.2.0" |
@@ -31,7 +31,7 @@ profile = { path = "../profile", version = "0.0.0" } | |||
31 | syntax = { path = "../syntax", version = "0.0.0" } | 31 | syntax = { path = "../syntax", version = "0.0.0" } |
32 | 32 | ||
33 | [dev-dependencies] | 33 | [dev-dependencies] |
34 | test_utils = { path = "../test_utils" } | 34 | test_utils = { path = "../test_utils" } |
35 | expect-test = "1.1" | 35 | expect-test = "1.1" |
36 | tracing = "0.1" | 36 | tracing = "0.1" |
37 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } | 37 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } |
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index be1fd1f13..56c6b92d4 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -12,9 +12,10 @@ use log::{info, warn}; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | to_assoc_type_id, | ||
15 | traits::{InEnvironment, Solution}, | 16 | traits::{InEnvironment, Solution}, |
16 | utils::generics, | 17 | utils::generics, |
17 | BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty, | 18 | BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind, |
18 | }; | 19 | }; |
19 | 20 | ||
20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 21 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
@@ -81,8 +82,12 @@ fn deref_by_trait( | |||
81 | 82 | ||
82 | // Now do the assoc type projection | 83 | // Now do the assoc type projection |
83 | let projection = super::traits::ProjectionPredicate { | 84 | let projection = super::traits::ProjectionPredicate { |
84 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), | 85 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) |
85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, | 86 | .intern(&Interner), |
87 | projection_ty: super::ProjectionTy { | ||
88 | associated_ty_id: to_assoc_type_id(target), | ||
89 | substitution: parameters, | ||
90 | }, | ||
86 | }; | 91 | }; |
87 | 92 | ||
88 | let obligation = super::Obligation::Projection(projection); | 93 | let obligation = super::Obligation::Projection(projection); |
@@ -114,8 +119,8 @@ fn deref_by_trait( | |||
114 | // new variables in that case | 119 | // new variables in that case |
115 | 120 | ||
116 | for i in 1..vars.0.kinds.len() { | 121 | for i in 1..vars.0.kinds.len() { |
117 | if vars.0.value[i - 1] | 122 | if vars.0.value[i - 1].interned(&Interner) |
118 | != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | 123 | != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) |
119 | { | 124 | { |
120 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); | 125 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); |
121 | return None; | 126 | return None; |
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 06714409f..74a048672 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -12,7 +12,7 @@ use la_arena::ArenaMap; | |||
12 | use crate::{ | 12 | use crate::{ |
13 | method_resolution::{InherentImpls, TraitImpls}, | 13 | method_resolution::{InherentImpls, TraitImpls}, |
14 | traits::chalk, | 14 | traits::chalk, |
15 | Binders, CallableDefId, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig, | 15 | Binders, CallableDefId, FnDefId, GenericPredicate, ImplTraitId, InferenceResult, PolyFnSig, |
16 | ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, | 16 | ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, |
17 | }; | 17 | }; |
18 | use hir_expand::name::Name; | 18 | use hir_expand::name::Name; |
@@ -65,6 +65,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
65 | #[salsa::invoke(crate::lower::generic_predicates_query)] | 65 | #[salsa::invoke(crate::lower::generic_predicates_query)] |
66 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; | 66 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; |
67 | 67 | ||
68 | #[salsa::invoke(crate::lower::trait_environment_query)] | ||
69 | fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; | ||
70 | |||
68 | #[salsa::invoke(crate::lower::generic_defaults_query)] | 71 | #[salsa::invoke(crate::lower::generic_defaults_query)] |
69 | fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; | 72 | fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; |
70 | 73 | ||
@@ -81,11 +84,11 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
81 | #[salsa::interned] | 84 | #[salsa::interned] |
82 | fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; | 85 | fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; |
83 | #[salsa::interned] | 86 | #[salsa::interned] |
84 | fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; | 87 | fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId; |
85 | #[salsa::interned] | 88 | #[salsa::interned] |
86 | fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; | 89 | fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; |
87 | #[salsa::interned] | 90 | #[salsa::interned] |
88 | fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> ClosureId; | 91 | fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId; |
89 | 92 | ||
90 | #[salsa::invoke(chalk::associated_ty_data_query)] | 93 | #[salsa::invoke(chalk::associated_ty_data_query)] |
91 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; | 94 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; |
@@ -100,10 +103,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
100 | fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; | 103 | fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; |
101 | 104 | ||
102 | #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] | 105 | #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] |
103 | fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc<chalk::FnDefDatum>; | 106 | fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>; |
104 | 107 | ||
105 | #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] | 108 | #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] |
106 | fn fn_def_variance(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> chalk::Variances; | 109 | fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances; |
107 | 110 | ||
108 | #[salsa::invoke(crate::traits::chalk::adt_variance_query)] | 111 | #[salsa::invoke(crate::traits::chalk::adt_variance_query)] |
109 | fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; | 112 | fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; |
@@ -149,16 +152,16 @@ fn hir_database_is_object_safe() { | |||
149 | } | 152 | } |
150 | 153 | ||
151 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 154 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
152 | pub struct GlobalTypeParamId(salsa::InternId); | 155 | pub struct InternedTypeParamId(salsa::InternId); |
153 | impl_intern_key!(GlobalTypeParamId); | 156 | impl_intern_key!(InternedTypeParamId); |
154 | 157 | ||
155 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 158 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
156 | pub struct InternedOpaqueTyId(salsa::InternId); | 159 | pub struct InternedOpaqueTyId(salsa::InternId); |
157 | impl_intern_key!(InternedOpaqueTyId); | 160 | impl_intern_key!(InternedOpaqueTyId); |
158 | 161 | ||
159 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 162 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
160 | pub struct ClosureId(salsa::InternId); | 163 | pub struct InternedClosureId(salsa::InternId); |
161 | impl_intern_key!(ClosureId); | 164 | impl_intern_key!(InternedClosureId); |
162 | 165 | ||
163 | /// This exists just for Chalk, because Chalk just has a single `FnDefId` where | 166 | /// This exists just for Chalk, because Chalk just has a single `FnDefId` where |
164 | /// we have different IDs for struct and enum variant constructors. | 167 | /// we have different IDs for struct and enum variant constructors. |
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 2751cd304..b2bfd68d4 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -15,7 +15,7 @@ use crate::{ | |||
15 | MissingPatFields, RemoveThisSemicolon, | 15 | MissingPatFields, RemoveThisSemicolon, |
16 | }, | 16 | }, |
17 | utils::variant_data, | 17 | utils::variant_data, |
18 | AdtId, InferenceResult, Ty, | 18 | AdtId, InferenceResult, Interner, Ty, TyKind, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | pub(crate) use hir_def::{ | 21 | pub(crate) use hir_def::{ |
@@ -289,11 +289,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
289 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = | 289 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = |
290 | db.body_with_source_map(self.owner.into()); | 290 | db.body_with_source_map(self.owner.into()); |
291 | 291 | ||
292 | let match_expr_ty = match infer.type_of_expr.get(match_expr) { | 292 | let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() { |
293 | // If we can't resolve the type of the match expression | 293 | return; |
294 | // we cannot perform exhaustiveness checks. | 294 | } else { |
295 | None | Some(Ty::Unknown) => return, | 295 | &infer.type_of_expr[match_expr] |
296 | Some(ty) => ty, | ||
297 | }; | 296 | }; |
298 | 297 | ||
299 | let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; | 298 | let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; |
@@ -379,14 +378,14 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
379 | _ => return, | 378 | _ => return, |
380 | }; | 379 | }; |
381 | 380 | ||
382 | let (params, required) = match mismatch.expected { | 381 | let (params, required) = match mismatch.expected.interned(&Interner) { |
383 | Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) | 382 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) |
384 | if enum_id == core_result_enum => | 383 | if *enum_id == core_result_enum => |
385 | { | 384 | { |
386 | (parameters, "Ok".to_string()) | 385 | (parameters, "Ok".to_string()) |
387 | } | 386 | } |
388 | Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) | 387 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) |
389 | if enum_id == core_option_enum => | 388 | if *enum_id == core_option_enum => |
390 | { | 389 | { |
391 | (parameters, "Some".to_string()) | 390 | (parameters, "Some".to_string()) |
392 | } | 391 | } |
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs index 04d39c571..5a5cdcbf3 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, AdtId, InferenceResult, Ty}; | 230 | use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyKind}; |
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 |
@@ -626,13 +626,13 @@ pub(super) fn is_useful( | |||
626 | // - enum with no variants | 626 | // - enum with no variants |
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().interned(&Interner) { |
630 | Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { | 630 | TyKind::Adt(AdtId(hir_def::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::Never => return Ok(Usefulness::NotUseful), | 635 | TyKind::Never => return Ok(Usefulness::NotUseful), |
636 | _ => (), | 636 | _ => (), |
637 | } | 637 | } |
638 | 638 | ||
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index e77a20fea..20bb64827 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | }; | 11 | }; |
12 | use hir_expand::diagnostics::DiagnosticSink; | 12 | use hir_expand::diagnostics::DiagnosticSink; |
13 | 13 | ||
14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty}; | 14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyKind}; |
15 | 15 | ||
16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { | 16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { |
17 | owner: DefWithBodyId, | 17 | owner: DefWithBodyId, |
@@ -85,7 +85,7 @@ fn walk_unsafe( | |||
85 | let expr = &body.exprs[current]; | 85 | let expr = &body.exprs[current]; |
86 | match expr { | 86 | match expr { |
87 | &Expr::Call { callee, .. } => { | 87 | &Expr::Call { callee, .. } => { |
88 | if let Some(func) = infer[callee].as_fn_def() { | 88 | if let Some(func) = infer[callee].as_fn_def(db) { |
89 | if db.function_data(func).is_unsafe { | 89 | if db.function_data(func).is_unsafe { |
90 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); | 90 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); |
91 | } | 91 | } |
@@ -110,7 +110,7 @@ fn walk_unsafe( | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { | 112 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { |
113 | if let Ty::Raw(..) = &infer[*expr] { | 113 | if let TyKind::Raw(..) = &infer[*expr].interned(&Interner) { |
114 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); | 114 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); |
115 | } | 115 | } |
116 | } | 116 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index ab51cb0a6..c1062387e 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -11,9 +11,10 @@ use hir_def::{ | |||
11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig, | 14 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, |
15 | GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, | 15 | to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId, |
16 | TraitRef, Ty, | 16 | CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy, |
17 | ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind, | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | pub struct HirFormatter<'a> { | 20 | pub struct HirFormatter<'a> { |
@@ -244,19 +245,19 @@ impl HirDisplay for ProjectionTy { | |||
244 | } | 245 | } |
245 | 246 | ||
246 | let trait_ = f.db.trait_data(self.trait_(f.db)); | 247 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
247 | let first_parameter = self.parameters[0].into_displayable( | 248 | let first_parameter = self.substitution[0].into_displayable( |
248 | f.db, | 249 | f.db, |
249 | f.max_size, | 250 | f.max_size, |
250 | f.omit_verbose_types, | 251 | f.omit_verbose_types, |
251 | f.display_target, | 252 | f.display_target, |
252 | ); | 253 | ); |
253 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | 254 | write!(f, "<{} as {}", first_parameter, trait_.name)?; |
254 | if self.parameters.len() > 1 { | 255 | if self.substitution.len() > 1 { |
255 | write!(f, "<")?; | 256 | write!(f, "<")?; |
256 | f.write_joined(&self.parameters[1..], ", ")?; | 257 | f.write_joined(&self.substitution[1..], ", ")?; |
257 | write!(f, ">")?; | 258 | write!(f, ">")?; |
258 | } | 259 | } |
259 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | 260 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; |
260 | Ok(()) | 261 | Ok(()) |
261 | } | 262 | } |
262 | } | 263 | } |
@@ -267,32 +268,29 @@ impl HirDisplay for Ty { | |||
267 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 268 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
268 | } | 269 | } |
269 | 270 | ||
270 | match self { | 271 | match self.interned(&Interner) { |
271 | Ty::Never => write!(f, "!")?, | 272 | TyKind::Never => write!(f, "!")?, |
272 | Ty::Str => write!(f, "str")?, | 273 | TyKind::Str => write!(f, "str")?, |
273 | Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, | 274 | TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, |
274 | Ty::Scalar(Scalar::Char) => write!(f, "char")?, | 275 | TyKind::Scalar(Scalar::Char) => write!(f, "char")?, |
275 | &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, | 276 | &TyKind::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, |
276 | &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, | 277 | &TyKind::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, |
277 | &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, | 278 | &TyKind::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, |
278 | Ty::Slice(parameters) => { | 279 | TyKind::Slice(t) => { |
279 | let t = parameters.as_single(); | ||
280 | write!(f, "[")?; | 280 | write!(f, "[")?; |
281 | t.hir_fmt(f)?; | 281 | t.hir_fmt(f)?; |
282 | write!(f, "]")?; | 282 | write!(f, "]")?; |
283 | } | 283 | } |
284 | Ty::Array(parameters) => { | 284 | TyKind::Array(t) => { |
285 | let t = parameters.as_single(); | ||
286 | write!(f, "[")?; | 285 | write!(f, "[")?; |
287 | t.hir_fmt(f)?; | 286 | t.hir_fmt(f)?; |
288 | write!(f, "; _]")?; | 287 | write!(f, "; _]")?; |
289 | } | 288 | } |
290 | Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { | 289 | TyKind::Raw(m, t) | TyKind::Ref(m, t) => { |
291 | let t = parameters.as_single(); | ||
292 | let ty_display = | 290 | let ty_display = |
293 | 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); |
294 | 292 | ||
295 | if matches!(self, Ty::Raw(..)) { | 293 | if matches!(self.interned(&Interner), TyKind::Raw(..)) { |
296 | write!( | 294 | write!( |
297 | f, | 295 | f, |
298 | "*{}", | 296 | "*{}", |
@@ -312,22 +310,29 @@ impl HirDisplay for Ty { | |||
312 | )?; | 310 | )?; |
313 | } | 311 | } |
314 | 312 | ||
313 | // FIXME: all this just to decide whether to use parentheses... | ||
315 | let datas; | 314 | let datas; |
316 | let predicates = match t { | 315 | let predicates = match t.interned(&Interner) { |
317 | Ty::Dyn(predicates) if predicates.len() > 1 => { | 316 | TyKind::Dyn(predicates) if predicates.len() > 1 => { |
318 | Cow::Borrowed(predicates.as_ref()) | 317 | Cow::Borrowed(predicates.as_ref()) |
319 | } | 318 | } |
320 | &Ty::Alias(AliasTy::Opaque(OpaqueTy { | 319 | &TyKind::Alias(AliasTy::Opaque(OpaqueTy { |
321 | opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), | 320 | opaque_ty_id, |
322 | ref parameters, | 321 | substitution: ref parameters, |
323 | })) => { | 322 | })) => { |
324 | datas = | 323 | let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into()); |
325 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 324 | if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id { |
326 | let data = (*datas) | 325 | datas = |
327 | .as_ref() | 326 | f.db.return_type_impl_traits(func) |
328 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 327 | .expect("impl trait id without data"); |
329 | let bounds = data.subst(parameters); | 328 | let data = (*datas) |
330 | Cow::Owned(bounds.value) | 329 | .as_ref() |
330 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
331 | let bounds = data.subst(parameters); | ||
332 | Cow::Owned(bounds.value) | ||
333 | } else { | ||
334 | Cow::Borrowed(&[][..]) | ||
335 | } | ||
331 | } | 336 | } |
332 | _ => Cow::Borrowed(&[][..]), | 337 | _ => Cow::Borrowed(&[][..]), |
333 | }; | 338 | }; |
@@ -347,7 +352,7 @@ impl HirDisplay for Ty { | |||
347 | write!(f, "{}", ty_display)?; | 352 | write!(f, "{}", ty_display)?; |
348 | } | 353 | } |
349 | } | 354 | } |
350 | Ty::Tuple(_, substs) => { | 355 | TyKind::Tuple(_, substs) => { |
351 | if substs.len() == 1 { | 356 | if substs.len() == 1 { |
352 | write!(f, "(")?; | 357 | write!(f, "(")?; |
353 | substs[0].hir_fmt(f)?; | 358 | substs[0].hir_fmt(f)?; |
@@ -358,12 +363,12 @@ impl HirDisplay for Ty { | |||
358 | write!(f, ")")?; | 363 | write!(f, ")")?; |
359 | } | 364 | } |
360 | } | 365 | } |
361 | Ty::Function(fn_ptr) => { | 366 | TyKind::Function(fn_ptr) => { |
362 | let sig = CallableSig::from_fn_ptr(fn_ptr); | 367 | let sig = CallableSig::from_fn_ptr(fn_ptr); |
363 | sig.hir_fmt(f)?; | 368 | sig.hir_fmt(f)?; |
364 | } | 369 | } |
365 | Ty::FnDef(def, parameters) => { | 370 | TyKind::FnDef(def, parameters) => { |
366 | let def = *def; | 371 | let def = from_chalk(f.db, *def); |
367 | let sig = f.db.callable_item_signature(def).subst(parameters); | 372 | let sig = f.db.callable_item_signature(def).subst(parameters); |
368 | match def { | 373 | match def { |
369 | CallableDefId::FunctionId(ff) => { | 374 | CallableDefId::FunctionId(ff) => { |
@@ -401,7 +406,7 @@ impl HirDisplay for Ty { | |||
401 | write!(f, " -> {}", ret_display)?; | 406 | write!(f, " -> {}", ret_display)?; |
402 | } | 407 | } |
403 | } | 408 | } |
404 | Ty::Adt(AdtId(def_id), parameters) => { | 409 | TyKind::Adt(AdtId(def_id), parameters) => { |
405 | match f.display_target { | 410 | match f.display_target { |
406 | DisplayTarget::Diagnostics | DisplayTarget::Test => { | 411 | DisplayTarget::Diagnostics | DisplayTarget::Test => { |
407 | let name = match *def_id { | 412 | let name = match *def_id { |
@@ -427,37 +432,39 @@ impl HirDisplay for Ty { | |||
427 | } | 432 | } |
428 | 433 | ||
429 | if parameters.len() > 0 { | 434 | if parameters.len() > 0 { |
430 | let parameters_to_write = | 435 | let parameters_to_write = if f.display_target.is_source_code() |
431 | if f.display_target.is_source_code() || f.omit_verbose_types() { | 436 | || f.omit_verbose_types() |
432 | match self | 437 | { |
433 | .as_generic_def() | 438 | match self |
434 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 439 | .as_generic_def(f.db) |
435 | .filter(|defaults| !defaults.is_empty()) | 440 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
436 | { | 441 | .filter(|defaults| !defaults.is_empty()) |
437 | None => parameters.0.as_ref(), | 442 | { |
438 | Some(default_parameters) => { | 443 | None => parameters.0.as_ref(), |
439 | let mut default_from = 0; | 444 | Some(default_parameters) => { |
440 | for (i, parameter) in parameters.iter().enumerate() { | 445 | let mut default_from = 0; |
441 | match (parameter, default_parameters.get(i)) { | 446 | for (i, parameter) in parameters.iter().enumerate() { |
442 | (&Ty::Unknown, _) | (_, None) => { | 447 | match (parameter.interned(&Interner), default_parameters.get(i)) |
448 | { | ||
449 | (&TyKind::Unknown, _) | (_, None) => { | ||
450 | default_from = i + 1; | ||
451 | } | ||
452 | (_, Some(default_parameter)) => { | ||
453 | let actual_default = default_parameter | ||
454 | .clone() | ||
455 | .subst(¶meters.prefix(i)); | ||
456 | if parameter != &actual_default { | ||
443 | default_from = i + 1; | 457 | default_from = i + 1; |
444 | } | 458 | } |
445 | (_, Some(default_parameter)) => { | ||
446 | let actual_default = default_parameter | ||
447 | .clone() | ||
448 | .subst(¶meters.prefix(i)); | ||
449 | if parameter != &actual_default { | ||
450 | default_from = i + 1; | ||
451 | } | ||
452 | } | ||
453 | } | 459 | } |
454 | } | 460 | } |
455 | ¶meters.0[0..default_from] | ||
456 | } | 461 | } |
462 | ¶meters.0[0..default_from] | ||
457 | } | 463 | } |
458 | } else { | 464 | } |
459 | parameters.0.as_ref() | 465 | } else { |
460 | }; | 466 | parameters.0.as_ref() |
467 | }; | ||
461 | if !parameters_to_write.is_empty() { | 468 | if !parameters_to_write.is_empty() { |
462 | write!(f, "<")?; | 469 | write!(f, "<")?; |
463 | f.write_joined(parameters_to_write, ", ")?; | 470 | f.write_joined(parameters_to_write, ", ")?; |
@@ -465,13 +472,14 @@ impl HirDisplay for Ty { | |||
465 | } | 472 | } |
466 | } | 473 | } |
467 | } | 474 | } |
468 | Ty::AssociatedType(type_alias, parameters) => { | 475 | TyKind::AssociatedType(assoc_type_id, parameters) => { |
476 | let type_alias = from_assoc_type_id(*assoc_type_id); | ||
469 | let trait_ = match type_alias.lookup(f.db.upcast()).container { | 477 | let trait_ = match type_alias.lookup(f.db.upcast()).container { |
470 | AssocContainerId::TraitId(it) => it, | 478 | AssocContainerId::TraitId(it) => it, |
471 | _ => panic!("not an associated type"), | 479 | _ => panic!("not an associated type"), |
472 | }; | 480 | }; |
473 | let trait_ = f.db.trait_data(trait_); | 481 | let trait_ = f.db.trait_data(trait_); |
474 | let type_alias_data = f.db.type_alias_data(*type_alias); | 482 | let type_alias_data = f.db.type_alias_data(type_alias); |
475 | 483 | ||
476 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) | 484 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
477 | if f.display_target.is_test() { | 485 | if f.display_target.is_test() { |
@@ -482,19 +490,22 @@ impl HirDisplay for Ty { | |||
482 | write!(f, ">")?; | 490 | write!(f, ">")?; |
483 | } | 491 | } |
484 | } else { | 492 | } else { |
485 | let projection_ty = | 493 | let projection_ty = ProjectionTy { |
486 | ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; | 494 | associated_ty_id: to_assoc_type_id(type_alias), |
495 | substitution: parameters.clone(), | ||
496 | }; | ||
487 | 497 | ||
488 | projection_ty.hir_fmt(f)?; | 498 | projection_ty.hir_fmt(f)?; |
489 | } | 499 | } |
490 | } | 500 | } |
491 | Ty::ForeignType(type_alias) => { | 501 | TyKind::ForeignType(type_alias) => { |
492 | let type_alias = f.db.type_alias_data(*type_alias); | 502 | let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); |
493 | write!(f, "{}", type_alias.name)?; | 503 | write!(f, "{}", type_alias.name)?; |
494 | } | 504 | } |
495 | Ty::OpaqueType(opaque_ty_id, parameters) => { | 505 | TyKind::OpaqueType(opaque_ty_id, parameters) => { |
496 | match opaque_ty_id { | 506 | let impl_trait_id = f.db.lookup_intern_impl_trait_id((*opaque_ty_id).into()); |
497 | &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 507 | match impl_trait_id { |
508 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
498 | let datas = | 509 | let datas = |
499 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 510 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
500 | let data = (*datas) | 511 | let data = (*datas) |
@@ -504,14 +515,14 @@ impl HirDisplay for Ty { | |||
504 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 515 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
505 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 516 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
506 | } | 517 | } |
507 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 518 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
508 | write!(f, "impl Future<Output = ")?; | 519 | write!(f, "impl Future<Output = ")?; |
509 | parameters[0].hir_fmt(f)?; | 520 | parameters[0].hir_fmt(f)?; |
510 | write!(f, ">")?; | 521 | write!(f, ">")?; |
511 | } | 522 | } |
512 | } | 523 | } |
513 | } | 524 | } |
514 | Ty::Closure(.., substs) => { | 525 | TyKind::Closure(.., substs) => { |
515 | let sig = substs[0].callable_sig(f.db); | 526 | let sig = substs[0].callable_sig(f.db); |
516 | if let Some(sig) = sig { | 527 | if let Some(sig) = sig { |
517 | if sig.params().is_empty() { | 528 | if sig.params().is_empty() { |
@@ -535,7 +546,8 @@ impl HirDisplay for Ty { | |||
535 | write!(f, "{{closure}}")?; | 546 | write!(f, "{{closure}}")?; |
536 | } | 547 | } |
537 | } | 548 | } |
538 | Ty::Placeholder(id) => { | 549 | TyKind::Placeholder(idx) => { |
550 | let id = from_placeholder_idx(f.db, *idx); | ||
539 | let generics = generics(f.db.upcast(), id.parent); | 551 | let generics = generics(f.db.upcast(), id.parent); |
540 | let param_data = &generics.params.types[id.local_id]; | 552 | let param_data = &generics.params.types[id.local_id]; |
541 | match param_data.provenance { | 553 | match param_data.provenance { |
@@ -543,8 +555,8 @@ impl HirDisplay for Ty { | |||
543 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? | 555 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? |
544 | } | 556 | } |
545 | TypeParamProvenance::ArgumentImplTrait => { | 557 | TypeParamProvenance::ArgumentImplTrait => { |
546 | let bounds = f.db.generic_predicates_for_param(*id); | 558 | let bounds = f.db.generic_predicates_for_param(id); |
547 | let substs = Substs::type_params_for_generics(&generics); | 559 | let substs = Substs::type_params_for_generics(f.db, &generics); |
548 | write_bounds_like_dyn_trait_with_prefix( | 560 | write_bounds_like_dyn_trait_with_prefix( |
549 | "impl", | 561 | "impl", |
550 | &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), | 562 | &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), |
@@ -553,28 +565,29 @@ impl HirDisplay for Ty { | |||
553 | } | 565 | } |
554 | } | 566 | } |
555 | } | 567 | } |
556 | Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 568 | TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, |
557 | Ty::Dyn(predicates) => { | 569 | TyKind::Dyn(predicates) => { |
558 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; | 570 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; |
559 | } | 571 | } |
560 | Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, | 572 | TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, |
561 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 573 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
562 | match opaque_ty.opaque_ty_id { | 574 | let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()); |
563 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 575 | match impl_trait_id { |
576 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
564 | let datas = | 577 | let datas = |
565 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 578 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
566 | let data = (*datas) | 579 | let data = (*datas) |
567 | .as_ref() | 580 | .as_ref() |
568 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 581 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
569 | let bounds = data.subst(&opaque_ty.parameters); | 582 | let bounds = data.subst(&opaque_ty.substitution); |
570 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 583 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
571 | } | 584 | } |
572 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 585 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
573 | write!(f, "{{async block}}")?; | 586 | write!(f, "{{async block}}")?; |
574 | } | 587 | } |
575 | }; | 588 | }; |
576 | } | 589 | } |
577 | Ty::Unknown => { | 590 | TyKind::Unknown => { |
578 | if f.display_target.is_source_code() { | 591 | if f.display_target.is_source_code() { |
579 | return Err(HirDisplayError::DisplaySourceCodeError( | 592 | return Err(HirDisplayError::DisplaySourceCodeError( |
580 | DisplaySourceCodeError::UnknownType, | 593 | DisplaySourceCodeError::UnknownType, |
@@ -582,7 +595,7 @@ impl HirDisplay for Ty { | |||
582 | } | 595 | } |
583 | write!(f, "{{unknown}}")?; | 596 | write!(f, "{{unknown}}")?; |
584 | } | 597 | } |
585 | Ty::InferenceVar(..) => write!(f, "_")?, | 598 | TyKind::InferenceVar(..) => write!(f, "_")?, |
586 | } | 599 | } |
587 | Ok(()) | 600 | Ok(()) |
588 | } | 601 | } |
@@ -695,7 +708,9 @@ fn write_bounds_like_dyn_trait( | |||
695 | write!(f, "<")?; | 708 | write!(f, "<")?; |
696 | angle_open = true; | 709 | angle_open = true; |
697 | } | 710 | } |
698 | let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty); | 711 | let type_alias = f.db.type_alias_data(from_assoc_type_id( |
712 | projection_pred.projection_ty.associated_ty_id, | ||
713 | )); | ||
699 | write!(f, "{} = ", type_alias.name)?; | 714 | write!(f, "{} = ", type_alias.name)?; |
700 | projection_pred.ty.hir_fmt(f)?; | 715 | projection_pred.ty.hir_fmt(f)?; |
701 | } | 716 | } |
@@ -766,7 +781,10 @@ impl HirDisplay for GenericPredicate { | |||
766 | write!( | 781 | write!( |
767 | f, | 782 | f, |
768 | ">::{} = ", | 783 | ">::{} = ", |
769 | f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, | 784 | f.db.type_alias_data(from_assoc_type_id( |
785 | projection_pred.projection_ty.associated_ty_id | ||
786 | )) | ||
787 | .name, | ||
770 | )?; | 788 | )?; |
771 | projection_pred.ty.hir_fmt(f)?; | 789 | projection_pred.ty.hir_fmt(f)?; |
772 | } | 790 | } |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 4d771a91e..9c385b845 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -41,7 +41,8 @@ use super::{ | |||
41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, | 41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 42 | }; |
43 | use crate::{ | 43 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
45 | to_assoc_type_id, AliasTy, Interner, TyKind, | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | pub(crate) use unify::unify; | 48 | pub(crate) use unify::unify; |
@@ -107,6 +108,17 @@ pub struct TypeMismatch { | |||
107 | pub actual: Ty, | 108 | pub actual: Ty, |
108 | } | 109 | } |
109 | 110 | ||
111 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
112 | struct InternedStandardTypes { | ||
113 | unknown: Ty, | ||
114 | } | ||
115 | |||
116 | impl Default for InternedStandardTypes { | ||
117 | fn default() -> Self { | ||
118 | InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) } | ||
119 | } | ||
120 | } | ||
121 | |||
110 | /// The result of type inference: A mapping from expressions and patterns to types. | 122 | /// The result of type inference: A mapping from expressions and patterns to types. |
111 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 123 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
112 | pub struct InferenceResult { | 124 | pub struct InferenceResult { |
@@ -125,6 +137,8 @@ pub struct InferenceResult { | |||
125 | pub type_of_expr: ArenaMap<ExprId, Ty>, | 137 | pub type_of_expr: ArenaMap<ExprId, Ty>, |
126 | pub type_of_pat: ArenaMap<PatId, Ty>, | 138 | pub type_of_pat: ArenaMap<PatId, Ty>, |
127 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, | 139 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, |
140 | /// Interned Unknown to return references to. | ||
141 | standard_types: InternedStandardTypes, | ||
128 | } | 142 | } |
129 | 143 | ||
130 | impl InferenceResult { | 144 | impl InferenceResult { |
@@ -169,7 +183,7 @@ impl Index<ExprId> for InferenceResult { | |||
169 | type Output = Ty; | 183 | type Output = Ty; |
170 | 184 | ||
171 | fn index(&self, expr: ExprId) -> &Ty { | 185 | fn index(&self, expr: ExprId) -> &Ty { |
172 | self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) | 186 | self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown) |
173 | } | 187 | } |
174 | } | 188 | } |
175 | 189 | ||
@@ -177,7 +191,7 @@ impl Index<PatId> for InferenceResult { | |||
177 | type Output = Ty; | 191 | type Output = Ty; |
178 | 192 | ||
179 | fn index(&self, pat: PatId) -> &Ty { | 193 | fn index(&self, pat: PatId) -> &Ty { |
180 | self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) | 194 | self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown) |
181 | } | 195 | } |
182 | } | 196 | } |
183 | 197 | ||
@@ -226,8 +240,10 @@ impl<'a> InferenceContext<'a> { | |||
226 | result: InferenceResult::default(), | 240 | result: InferenceResult::default(), |
227 | table: unify::InferenceTable::new(), | 241 | table: unify::InferenceTable::new(), |
228 | obligations: Vec::default(), | 242 | obligations: Vec::default(), |
229 | return_ty: Ty::Unknown, // set in collect_fn_signature | 243 | return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature |
230 | trait_env: TraitEnvironment::lower(db, &resolver), | 244 | trait_env: owner |
245 | .as_generic_def_id() | ||
246 | .map_or_else(Default::default, |d| db.trait_environment(d)), | ||
231 | db, | 247 | db, |
232 | owner, | 248 | owner, |
233 | body: db.body(owner), | 249 | body: db.body(owner), |
@@ -237,15 +253,19 @@ impl<'a> InferenceContext<'a> { | |||
237 | } | 253 | } |
238 | } | 254 | } |
239 | 255 | ||
256 | fn err_ty(&self) -> Ty { | ||
257 | TyKind::Unknown.intern(&Interner) | ||
258 | } | ||
259 | |||
240 | fn resolve_all(mut self) -> InferenceResult { | 260 | fn resolve_all(mut self) -> InferenceResult { |
241 | // FIXME resolve obligations as well (use Guidance if necessary) | 261 | // FIXME resolve obligations as well (use Guidance if necessary) |
242 | let mut result = std::mem::take(&mut self.result); | 262 | let mut result = std::mem::take(&mut self.result); |
243 | for ty in result.type_of_expr.values_mut() { | 263 | for ty in result.type_of_expr.values_mut() { |
244 | let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | 264 | let resolved = self.table.resolve_ty_completely(ty.clone()); |
245 | *ty = resolved; | 265 | *ty = resolved; |
246 | } | 266 | } |
247 | for ty in result.type_of_pat.values_mut() { | 267 | for ty in result.type_of_pat.values_mut() { |
248 | let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | 268 | let resolved = self.table.resolve_ty_completely(ty.clone()); |
249 | *ty = resolved; | 269 | *ty = resolved; |
250 | } | 270 | } |
251 | result | 271 | result |
@@ -287,7 +307,7 @@ impl<'a> InferenceContext<'a> { | |||
287 | // FIXME use right resolver for block | 307 | // FIXME use right resolver for block |
288 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) | 308 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) |
289 | .with_impl_trait_mode(impl_trait_mode); | 309 | .with_impl_trait_mode(impl_trait_mode); |
290 | let ty = Ty::from_hir(&ctx, type_ref); | 310 | let ty = ctx.lower_ty(type_ref); |
291 | let ty = self.insert_type_vars(ty); | 311 | let ty = self.insert_type_vars(ty); |
292 | self.normalize_associated_types_in(ty) | 312 | self.normalize_associated_types_in(ty) |
293 | } | 313 | } |
@@ -298,8 +318,8 @@ impl<'a> InferenceContext<'a> { | |||
298 | 318 | ||
299 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 319 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
300 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 320 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
301 | match ty { | 321 | match ty.interned(&Interner) { |
302 | Ty::Unknown => self.table.new_type_var(), | 322 | TyKind::Unknown => self.table.new_type_var(), |
303 | _ => ty, | 323 | _ => ty, |
304 | } | 324 | } |
305 | } | 325 | } |
@@ -377,13 +397,16 @@ impl<'a> InferenceContext<'a> { | |||
377 | let trait_ref = TraitRef { trait_, substs: substs.clone() }; | 397 | let trait_ref = TraitRef { trait_, substs: substs.clone() }; |
378 | let projection = ProjectionPredicate { | 398 | let projection = ProjectionPredicate { |
379 | ty: ty.clone(), | 399 | ty: ty.clone(), |
380 | projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs }, | 400 | projection_ty: ProjectionTy { |
401 | associated_ty_id: to_assoc_type_id(res_assoc_ty), | ||
402 | substitution: substs, | ||
403 | }, | ||
381 | }; | 404 | }; |
382 | self.obligations.push(Obligation::Trait(trait_ref)); | 405 | self.obligations.push(Obligation::Trait(trait_ref)); |
383 | self.obligations.push(Obligation::Projection(projection)); | 406 | self.obligations.push(Obligation::Projection(projection)); |
384 | self.resolve_ty_as_possible(ty) | 407 | self.resolve_ty_as_possible(ty) |
385 | } | 408 | } |
386 | None => Ty::Unknown, | 409 | None => self.err_ty(), |
387 | } | 410 | } |
388 | } | 411 | } |
389 | 412 | ||
@@ -395,8 +418,10 @@ impl<'a> InferenceContext<'a> { | |||
395 | /// to do it as well. | 418 | /// to do it as well. |
396 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { | 419 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { |
397 | let ty = self.resolve_ty_as_possible(ty); | 420 | let ty = self.resolve_ty_as_possible(ty); |
398 | ty.fold(&mut |ty| match ty { | 421 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
399 | Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), | 422 | TyKind::Alias(AliasTy::Projection(proj_ty)) => { |
423 | self.normalize_projection_ty(proj_ty.clone()) | ||
424 | } | ||
400 | _ => ty, | 425 | _ => ty, |
401 | }) | 426 | }) |
402 | } | 427 | } |
@@ -412,7 +437,7 @@ impl<'a> InferenceContext<'a> { | |||
412 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { | 437 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { |
413 | let path = match path { | 438 | let path = match path { |
414 | Some(path) => path, | 439 | Some(path) => path, |
415 | None => return (Ty::Unknown, None), | 440 | None => return (self.err_ty(), None), |
416 | }; | 441 | }; |
417 | let resolver = &self.resolver; | 442 | let resolver = &self.resolver; |
418 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 443 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
@@ -421,30 +446,30 @@ impl<'a> InferenceContext<'a> { | |||
421 | let (resolution, unresolved) = | 446 | let (resolution, unresolved) = |
422 | match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { | 447 | match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { |
423 | Some(it) => it, | 448 | Some(it) => it, |
424 | None => return (Ty::Unknown, None), | 449 | None => return (self.err_ty(), None), |
425 | }; | 450 | }; |
426 | return match resolution { | 451 | return match resolution { |
427 | TypeNs::AdtId(AdtId::StructId(strukt)) => { | 452 | TypeNs::AdtId(AdtId::StructId(strukt)) => { |
428 | let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true); | 453 | let substs = ctx.substs_from_path(path, strukt.into(), true); |
429 | let ty = self.db.ty(strukt.into()); | 454 | let ty = self.db.ty(strukt.into()); |
430 | let ty = self.insert_type_vars(ty.subst(&substs)); | 455 | let ty = self.insert_type_vars(ty.subst(&substs)); |
431 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) | 456 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) |
432 | } | 457 | } |
433 | TypeNs::AdtId(AdtId::UnionId(u)) => { | 458 | TypeNs::AdtId(AdtId::UnionId(u)) => { |
434 | let substs = Ty::substs_from_path(&ctx, path, u.into(), true); | 459 | let substs = ctx.substs_from_path(path, u.into(), true); |
435 | let ty = self.db.ty(u.into()); | 460 | let ty = self.db.ty(u.into()); |
436 | let ty = self.insert_type_vars(ty.subst(&substs)); | 461 | let ty = self.insert_type_vars(ty.subst(&substs)); |
437 | forbid_unresolved_segments((ty, Some(u.into())), unresolved) | 462 | forbid_unresolved_segments((ty, Some(u.into())), unresolved) |
438 | } | 463 | } |
439 | TypeNs::EnumVariantId(var) => { | 464 | TypeNs::EnumVariantId(var) => { |
440 | let substs = Ty::substs_from_path(&ctx, path, var.into(), true); | 465 | let substs = ctx.substs_from_path(path, var.into(), true); |
441 | let ty = self.db.ty(var.parent.into()); | 466 | let ty = self.db.ty(var.parent.into()); |
442 | let ty = self.insert_type_vars(ty.subst(&substs)); | 467 | let ty = self.insert_type_vars(ty.subst(&substs)); |
443 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) | 468 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) |
444 | } | 469 | } |
445 | TypeNs::SelfType(impl_id) => { | 470 | TypeNs::SelfType(impl_id) => { |
446 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 471 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
447 | let substs = Substs::type_params_for_generics(&generics); | 472 | let substs = Substs::type_params_for_generics(self.db, &generics); |
448 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 473 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); |
449 | match unresolved { | 474 | match unresolved { |
450 | None => { | 475 | None => { |
@@ -462,11 +487,11 @@ impl<'a> InferenceContext<'a> { | |||
462 | } | 487 | } |
463 | } | 488 | } |
464 | // FIXME potentially resolve assoc type | 489 | // FIXME potentially resolve assoc type |
465 | (Ty::Unknown, None) | 490 | (self.err_ty(), None) |
466 | } | 491 | } |
467 | Some(_) => { | 492 | Some(_) => { |
468 | // FIXME diagnostic | 493 | // FIXME diagnostic |
469 | (Ty::Unknown, None) | 494 | (self.err_ty(), None) |
470 | } | 495 | } |
471 | } | 496 | } |
472 | } | 497 | } |
@@ -480,15 +505,15 @@ impl<'a> InferenceContext<'a> { | |||
480 | } | 505 | } |
481 | TypeNs::AdtSelfType(_) => { | 506 | TypeNs::AdtSelfType(_) => { |
482 | // FIXME this could happen in array size expressions, once we're checking them | 507 | // FIXME this could happen in array size expressions, once we're checking them |
483 | (Ty::Unknown, None) | 508 | (self.err_ty(), None) |
484 | } | 509 | } |
485 | TypeNs::GenericParam(_) => { | 510 | TypeNs::GenericParam(_) => { |
486 | // FIXME potentially resolve assoc type | 511 | // FIXME potentially resolve assoc type |
487 | (Ty::Unknown, None) | 512 | (self.err_ty(), None) |
488 | } | 513 | } |
489 | TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { | 514 | TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { |
490 | // FIXME diagnostic | 515 | // FIXME diagnostic |
491 | (Ty::Unknown, None) | 516 | (self.err_ty(), None) |
492 | } | 517 | } |
493 | }; | 518 | }; |
494 | 519 | ||
@@ -500,7 +525,7 @@ impl<'a> InferenceContext<'a> { | |||
500 | result | 525 | result |
501 | } else { | 526 | } else { |
502 | // FIXME diagnostic | 527 | // FIXME diagnostic |
503 | (Ty::Unknown, None) | 528 | (TyKind::Unknown.intern(&Interner), None) |
504 | } | 529 | } |
505 | } | 530 | } |
506 | 531 | ||
@@ -529,7 +554,7 @@ impl<'a> InferenceContext<'a> { | |||
529 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) | 554 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) |
530 | .with_impl_trait_mode(ImplTraitLoweringMode::Param); | 555 | .with_impl_trait_mode(ImplTraitLoweringMode::Param); |
531 | let param_tys = | 556 | let param_tys = |
532 | data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>(); | 557 | data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(); |
533 | for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { | 558 | for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { |
534 | let ty = self.insert_type_vars(ty); | 559 | let ty = self.insert_type_vars(ty); |
535 | let ty = self.normalize_associated_types_in(ty); | 560 | let ty = self.normalize_associated_types_in(ty); |
@@ -711,14 +736,19 @@ impl Expectation { | |||
711 | 736 | ||
712 | /// This expresses no expectation on the type. | 737 | /// This expresses no expectation on the type. |
713 | fn none() -> Self { | 738 | fn none() -> Self { |
714 | Expectation { ty: Ty::Unknown, rvalue_hint: false } | 739 | Expectation { |
740 | // FIXME | ||
741 | ty: TyKind::Unknown.intern(&Interner), | ||
742 | rvalue_hint: false, | ||
743 | } | ||
715 | } | 744 | } |
716 | 745 | ||
717 | fn coercion_target(&self) -> &Ty { | 746 | fn coercion_target(&self) -> Ty { |
718 | if self.rvalue_hint { | 747 | if self.rvalue_hint { |
719 | &Ty::Unknown | 748 | // FIXME |
749 | TyKind::Unknown.intern(&Interner) | ||
720 | } else { | 750 | } else { |
721 | &self.ty | 751 | self.ty.clone() |
722 | } | 752 | } |
723 | } | 753 | } |
724 | } | 754 | } |
@@ -772,7 +802,7 @@ mod diagnostics { | |||
772 | 802 | ||
773 | #[derive(Debug, PartialEq, Eq, Clone)] | 803 | #[derive(Debug, PartialEq, Eq, Clone)] |
774 | pub(super) enum InferenceDiagnostic { | 804 | pub(super) enum InferenceDiagnostic { |
775 | NoSuchField { expr: ExprId, field: usize }, | 805 | NoSuchField { expr: ExprId }, |
776 | BreakOutsideOfLoop { expr: ExprId }, | 806 | BreakOutsideOfLoop { expr: ExprId }, |
777 | } | 807 | } |
778 | 808 | ||
@@ -784,9 +814,9 @@ mod diagnostics { | |||
784 | sink: &mut DiagnosticSink, | 814 | sink: &mut DiagnosticSink, |
785 | ) { | 815 | ) { |
786 | match self { | 816 | match self { |
787 | InferenceDiagnostic::NoSuchField { expr, field } => { | 817 | InferenceDiagnostic::NoSuchField { expr } => { |
788 | let (_, source_map) = db.body_with_source_map(owner); | 818 | let (_, source_map) = db.body_with_source_map(owner); |
789 | let field = source_map.field_syntax(*expr, *field); | 819 | let field = source_map.field_syntax(*expr); |
790 | sink.push(NoSuchField { file: field.file_id, field: field.value }) | 820 | sink.push(NoSuchField { file: field.file_id, field: field.value }) |
791 | } | 821 | } |
792 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { | 822 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { |
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 7e8846f27..137419264 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use chalk_ir::{Mutability, TyVariableKind}; | 7 | use chalk_ir::{Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; | 10 | use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
13 | 13 | ||
@@ -33,7 +33,9 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 33 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 34 | ty1.clone() |
35 | } else { | 35 | } else { |
36 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { | 36 | if let (TyKind::FnDef(..), TyKind::FnDef(..)) = |
37 | (ty1.interned(&Interner), ty2.interned(&Interner)) | ||
38 | { | ||
37 | cov_mark::hit!(coerce_fn_reification); | 39 | cov_mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 40 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 41 | // pointers to have a chance at getting a match. See |
@@ -51,13 +53,13 @@ impl<'a> InferenceContext<'a> { | |||
51 | } | 53 | } |
52 | 54 | ||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 55 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 56 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 57 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { | 58 | (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { |
57 | self.table.type_variable_table.set_diverging(*tv, true); | 59 | self.table.type_variable_table.set_diverging(*tv, true); |
58 | return true; | 60 | return true; |
59 | } | 61 | } |
60 | (Ty::Never, _) => return true, | 62 | (TyKind::Never, _) => return true, |
61 | 63 | ||
62 | // Trivial cases, this should go after `never` check to | 64 | // Trivial cases, this should go after `never` check to |
63 | // avoid infer result type to be never | 65 | // avoid infer result type to be never |
@@ -69,33 +71,33 @@ impl<'a> InferenceContext<'a> { | |||
69 | } | 71 | } |
70 | 72 | ||
71 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
72 | match (&mut from_ty, to_ty) { | 74 | match (from_ty.interned_mut(), to_ty.interned(&Interner)) { |
73 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
74 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
75 | (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
76 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { | 78 | | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { |
77 | *m1 = *m2; | 79 | *m1 = *m2; |
78 | } | 80 | } |
79 | // `&T` -> `*const T` | 81 | // `&T` -> `*const T` |
80 | // `&mut T` -> `*mut T`/`*const T` | 82 | // `&mut T` -> `*mut T`/`*const T` |
81 | (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | 83 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) |
82 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | 84 | | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { |
83 | from_ty = Ty::Raw(m2, substs.clone()); | 85 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); |
84 | } | 86 | } |
85 | 87 | ||
86 | // Illegal mutability conversion | 88 | // Illegal mutability conversion |
87 | (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) | 89 | (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..)) |
88 | | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, | 90 | | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false, |
89 | 91 | ||
90 | // `{function_type}` -> `fn()` | 92 | // `{function_type}` -> `fn()` |
91 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { | 93 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { |
92 | None => return false, | 94 | None => return false, |
93 | Some(sig) => { | 95 | Some(sig) => { |
94 | from_ty = Ty::fn_ptr(sig); | 96 | from_ty = Ty::fn_ptr(sig); |
95 | } | 97 | } |
96 | }, | 98 | }, |
97 | 99 | ||
98 | (Ty::Closure(.., substs), Ty::Function { .. }) => { | 100 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { |
99 | from_ty = substs[0].clone(); | 101 | from_ty = substs[0].clone(); |
100 | } | 102 | } |
101 | 103 | ||
@@ -107,9 +109,9 @@ impl<'a> InferenceContext<'a> { | |||
107 | } | 109 | } |
108 | 110 | ||
109 | // Auto Deref if cannot coerce | 111 | // Auto Deref if cannot coerce |
110 | match (&from_ty, to_ty) { | 112 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
111 | // FIXME: DerefMut | 113 | // FIXME: DerefMut |
112 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), | 114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), |
113 | 115 | ||
114 | // Otherwise, normal unify | 116 | // Otherwise, normal unify |
115 | _ => self.unify(&from_ty, to_ty), | 117 | _ => self.unify(&from_ty, to_ty), |
@@ -174,11 +176,7 @@ impl<'a> InferenceContext<'a> { | |||
174 | // Stop when constructor matches. | 176 | // Stop when constructor matches. |
175 | if from_ty.equals_ctor(&to_ty) { | 177 | if from_ty.equals_ctor(&to_ty) { |
176 | // It will not recurse to `coerce`. | 178 | // It will not recurse to `coerce`. |
177 | return match (from_ty.substs(), to_ty.substs()) { | 179 | return self.table.unify(&from_ty, &to_ty); |
178 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), | ||
179 | (None, None) => true, | ||
180 | _ => false, | ||
181 | }; | ||
182 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 180 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
183 | return true; | 181 | return true; |
184 | } | 182 | } |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 262177ffb..f40dec17f 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -18,10 +18,11 @@ use crate::{ | |||
18 | lower::lower_to_chalk_mutability, | 18 | lower::lower_to_chalk_mutability, |
19 | method_resolution, op, | 19 | method_resolution, op, |
20 | primitive::{self, UintTy}, | 20 | primitive::{self, UintTy}, |
21 | traits::{FnTrait, InEnvironment}, | 21 | to_assoc_type_id, |
22 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, | ||
22 | utils::{generics, variant_data, Generics}, | 23 | utils::{generics, variant_data, Generics}, |
23 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, | 24 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs, |
24 | Substs, TraitRef, Ty, | 25 | TraitRef, Ty, TyKind, |
25 | }; | 26 | }; |
26 | 27 | ||
27 | use super::{ | 28 | use super::{ |
@@ -57,7 +58,7 @@ impl<'a> InferenceContext<'a> { | |||
57 | // Return actual type when type mismatch. | 58 | // Return actual type when type mismatch. |
58 | // This is needed for diagnostic when return type mismatch. | 59 | // This is needed for diagnostic when return type mismatch. |
59 | ty | 60 | ty |
60 | } else if expected.coercion_target() == &Ty::Unknown { | 61 | } else if expected.coercion_target().is_unknown() { |
61 | ty | 62 | ty |
62 | } else { | 63 | } else { |
63 | expected.ty.clone() | 64 | expected.ty.clone() |
@@ -84,7 +85,7 @@ impl<'a> InferenceContext<'a> { | |||
84 | arg_tys.push(arg); | 85 | arg_tys.push(arg); |
85 | } | 86 | } |
86 | let parameters = param_builder.build(); | 87 | let parameters = param_builder.build(); |
87 | let arg_ty = Ty::Tuple(num_args, parameters); | 88 | let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); |
88 | let substs = | 89 | let substs = |
89 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
90 | 91 | ||
@@ -97,8 +98,10 @@ impl<'a> InferenceContext<'a> { | |||
97 | }); | 98 | }); |
98 | if self.db.trait_solve(krate, goal.value).is_some() { | 99 | if self.db.trait_solve(krate, goal.value).is_some() { |
99 | self.obligations.push(implements_fn_trait); | 100 | self.obligations.push(implements_fn_trait); |
100 | let output_proj_ty = | 101 | let output_proj_ty = crate::ProjectionTy { |
101 | crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; | 102 | associated_ty_id: to_assoc_type_id(output_assoc_type), |
103 | substitution: substs, | ||
104 | }; | ||
102 | let return_ty = self.normalize_projection_ty(output_proj_ty); | 105 | let return_ty = self.normalize_projection_ty(output_proj_ty); |
103 | Some((arg_tys, return_ty)) | 106 | Some((arg_tys, return_ty)) |
104 | } else { | 107 | } else { |
@@ -116,10 +119,13 @@ impl<'a> InferenceContext<'a> { | |||
116 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 119 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
117 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 120 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
118 | let ty = match &body[tgt_expr] { | 121 | let ty = match &body[tgt_expr] { |
119 | Expr::Missing => Ty::Unknown, | 122 | Expr::Missing => self.err_ty(), |
120 | Expr::If { condition, then_branch, else_branch } => { | 123 | Expr::If { condition, then_branch, else_branch } => { |
121 | // if let is desugared to match, so this is always simple if | 124 | // if let is desugared to match, so this is always simple if |
122 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 125 | self.infer_expr( |
126 | *condition, | ||
127 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
128 | ); | ||
123 | 129 | ||
124 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 130 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
125 | let mut both_arms_diverge = Diverges::Always; | 131 | let mut both_arms_diverge = Diverges::Always; |
@@ -167,14 +173,15 @@ impl<'a> InferenceContext<'a> { | |||
167 | Expr::TryBlock { body } => { | 173 | Expr::TryBlock { body } => { |
168 | let _inner = self.infer_expr(*body, expected); | 174 | let _inner = self.infer_expr(*body, expected); |
169 | // FIXME should be std::result::Result<{inner}, _> | 175 | // FIXME should be std::result::Result<{inner}, _> |
170 | Ty::Unknown | 176 | self.err_ty() |
171 | } | 177 | } |
172 | Expr::Async { body } => { | 178 | Expr::Async { body } => { |
173 | // Use the first type parameter as the output type of future. | 179 | // Use the first type parameter as the output type of future. |
174 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 180 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
175 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 181 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
176 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 182 | let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); |
177 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) | 183 | let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); |
184 | TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner) | ||
178 | } | 185 | } |
179 | Expr::Loop { body, label } => { | 186 | Expr::Loop { body, label } => { |
180 | self.breakables.push(BreakableContext { | 187 | self.breakables.push(BreakableContext { |
@@ -192,17 +199,20 @@ impl<'a> InferenceContext<'a> { | |||
192 | if ctxt.may_break { | 199 | if ctxt.may_break { |
193 | ctxt.break_ty | 200 | ctxt.break_ty |
194 | } else { | 201 | } else { |
195 | Ty::Never | 202 | TyKind::Never.intern(&Interner) |
196 | } | 203 | } |
197 | } | 204 | } |
198 | Expr::While { condition, body, label } => { | 205 | Expr::While { condition, body, label } => { |
199 | self.breakables.push(BreakableContext { | 206 | self.breakables.push(BreakableContext { |
200 | may_break: false, | 207 | may_break: false, |
201 | break_ty: Ty::Unknown, | 208 | break_ty: self.err_ty(), |
202 | label: label.map(|label| self.body[label].name.clone()), | 209 | label: label.map(|label| self.body[label].name.clone()), |
203 | }); | 210 | }); |
204 | // while let is desugared to a match loop, so this is always simple while | 211 | // while let is desugared to a match loop, so this is always simple while |
205 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 212 | self.infer_expr( |
213 | *condition, | ||
214 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
215 | ); | ||
206 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 216 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
207 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 217 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
208 | // the body may not run, so it diverging doesn't mean we diverge | 218 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -214,7 +224,7 @@ impl<'a> InferenceContext<'a> { | |||
214 | 224 | ||
215 | self.breakables.push(BreakableContext { | 225 | self.breakables.push(BreakableContext { |
216 | may_break: false, | 226 | may_break: false, |
217 | break_ty: Ty::Unknown, | 227 | break_ty: self.err_ty(), |
218 | label: label.map(|label| self.body[label].name.clone()), | 228 | label: label.map(|label| self.body[label].name.clone()), |
219 | }); | 229 | }); |
220 | let pat_ty = | 230 | let pat_ty = |
@@ -249,12 +259,15 @@ impl<'a> InferenceContext<'a> { | |||
249 | None => self.table.new_type_var(), | 259 | None => self.table.new_type_var(), |
250 | }; | 260 | }; |
251 | sig_tys.push(ret_ty.clone()); | 261 | sig_tys.push(ret_ty.clone()); |
252 | let sig_ty = Ty::Function(FnPointer { | 262 | let sig_ty = TyKind::Function(FnPointer { |
253 | num_args: sig_tys.len() - 1, | 263 | num_args: sig_tys.len() - 1, |
254 | sig: FnSig { variadic: false }, | 264 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, |
255 | substs: Substs(sig_tys.clone().into()), | 265 | substs: Substs(sig_tys.clone().into()), |
256 | }); | 266 | }) |
257 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); | 267 | .intern(&Interner); |
268 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); | ||
269 | let closure_ty = | ||
270 | TyKind::Closure(closure_id, Substs::single(sig_ty)).intern(&Interner); | ||
258 | 271 | ||
259 | // Eagerly try to relate the closure type with the expected | 272 | // Eagerly try to relate the closure type with the expected |
260 | // type, otherwise we often won't have enough information to | 273 | // type, otherwise we often won't have enough information to |
@@ -295,7 +308,7 @@ impl<'a> InferenceContext<'a> { | |||
295 | args.len(), | 308 | args.len(), |
296 | ) | 309 | ) |
297 | }) | 310 | }) |
298 | .unwrap_or((Vec::new(), Ty::Unknown)); | 311 | .unwrap_or((Vec::new(), self.err_ty())); |
299 | self.register_obligations_for_call(&callee_ty); | 312 | self.register_obligations_for_call(&callee_ty); |
300 | self.check_call_arguments(args, ¶m_tys); | 313 | self.check_call_arguments(args, ¶m_tys); |
301 | self.normalize_associated_types_in(ret_ty) | 314 | self.normalize_associated_types_in(ret_ty) |
@@ -305,8 +318,11 @@ impl<'a> InferenceContext<'a> { | |||
305 | Expr::Match { expr, arms } => { | 318 | Expr::Match { expr, arms } => { |
306 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 319 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
307 | 320 | ||
308 | let mut result_ty = | 321 | let mut result_ty = if arms.is_empty() { |
309 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; | 322 | TyKind::Never.intern(&Interner) |
323 | } else { | ||
324 | self.table.new_type_var() | ||
325 | }; | ||
310 | 326 | ||
311 | let matchee_diverges = self.diverges; | 327 | let matchee_diverges = self.diverges; |
312 | let mut all_arms_diverge = Diverges::Always; | 328 | let mut all_arms_diverge = Diverges::Always; |
@@ -317,7 +333,7 @@ impl<'a> InferenceContext<'a> { | |||
317 | if let Some(guard_expr) = arm.guard { | 333 | if let Some(guard_expr) = arm.guard { |
318 | self.infer_expr( | 334 | self.infer_expr( |
319 | guard_expr, | 335 | guard_expr, |
320 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 336 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), |
321 | ); | 337 | ); |
322 | } | 338 | } |
323 | 339 | ||
@@ -333,9 +349,9 @@ impl<'a> InferenceContext<'a> { | |||
333 | Expr::Path(p) => { | 349 | Expr::Path(p) => { |
334 | // FIXME this could be more efficient... | 350 | // FIXME this could be more efficient... |
335 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 351 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
336 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 352 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty()) |
337 | } | 353 | } |
338 | Expr::Continue { .. } => Ty::Never, | 354 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), |
339 | Expr::Break { expr, label } => { | 355 | Expr::Break { expr, label } => { |
340 | let val_ty = if let Some(expr) = expr { | 356 | let val_ty = if let Some(expr) = expr { |
341 | self.infer_expr(*expr, &Expectation::none()) | 357 | self.infer_expr(*expr, &Expectation::none()) |
@@ -347,7 +363,7 @@ impl<'a> InferenceContext<'a> { | |||
347 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 363 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
348 | ctxt.break_ty.clone() | 364 | ctxt.break_ty.clone() |
349 | } else { | 365 | } else { |
350 | Ty::Unknown | 366 | self.err_ty() |
351 | }; | 367 | }; |
352 | 368 | ||
353 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | 369 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); |
@@ -360,7 +376,7 @@ impl<'a> InferenceContext<'a> { | |||
360 | expr: tgt_expr, | 376 | expr: tgt_expr, |
361 | }); | 377 | }); |
362 | } | 378 | } |
363 | Ty::Never | 379 | TyKind::Never.intern(&Interner) |
364 | } | 380 | } |
365 | Expr::Return { expr } => { | 381 | Expr::Return { expr } => { |
366 | if let Some(expr) = expr { | 382 | if let Some(expr) = expr { |
@@ -369,14 +385,14 @@ impl<'a> InferenceContext<'a> { | |||
369 | let unit = Ty::unit(); | 385 | let unit = Ty::unit(); |
370 | self.coerce(&unit, &self.return_ty.clone()); | 386 | self.coerce(&unit, &self.return_ty.clone()); |
371 | } | 387 | } |
372 | Ty::Never | 388 | TyKind::Never.intern(&Interner) |
373 | } | 389 | } |
374 | Expr::Yield { expr } => { | 390 | Expr::Yield { expr } => { |
375 | // FIXME: track yield type for coercion | 391 | // FIXME: track yield type for coercion |
376 | if let Some(expr) = expr { | 392 | if let Some(expr) = expr { |
377 | self.infer_expr(*expr, &Expectation::none()); | 393 | self.infer_expr(*expr, &Expectation::none()); |
378 | } | 394 | } |
379 | Ty::Never | 395 | TyKind::Never.intern(&Interner) |
380 | } | 396 | } |
381 | Expr::RecordLit { path, fields, spread } => { | 397 | Expr::RecordLit { path, fields, spread } => { |
382 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 398 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -389,14 +405,13 @@ impl<'a> InferenceContext<'a> { | |||
389 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); | 405 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
390 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 406 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
391 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 407 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
392 | for (field_idx, field) in fields.iter().enumerate() { | 408 | for field in fields.iter() { |
393 | let field_def = | 409 | let field_def = |
394 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { | 410 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { |
395 | Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), | 411 | Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), |
396 | None => { | 412 | None => { |
397 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { | 413 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { |
398 | expr: tgt_expr, | 414 | expr: field.expr, |
399 | field: field_idx, | ||
400 | }); | 415 | }); |
401 | None | 416 | None |
402 | } | 417 | } |
@@ -404,8 +419,9 @@ impl<'a> InferenceContext<'a> { | |||
404 | if let Some(field_def) = field_def { | 419 | if let Some(field_def) = field_def { |
405 | self.result.record_field_resolutions.insert(field.expr, field_def); | 420 | self.result.record_field_resolutions.insert(field.expr, field_def); |
406 | } | 421 | } |
407 | let field_ty = field_def | 422 | let field_ty = field_def.map_or(self.err_ty(), |it| { |
408 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); | 423 | field_types[it.local_id].clone().subst(&substs) |
424 | }); | ||
409 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 425 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
410 | } | 426 | } |
411 | if let Some(expr) = spread { | 427 | if let Some(expr) = spread { |
@@ -424,27 +440,33 @@ impl<'a> InferenceContext<'a> { | |||
424 | environment: self.trait_env.clone(), | 440 | environment: self.trait_env.clone(), |
425 | }, | 441 | }, |
426 | ) | 442 | ) |
427 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 443 | .find_map(|derefed_ty| { |
428 | Ty::Tuple(_, substs) => { | 444 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { |
429 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 445 | TyKind::Tuple(_, substs) => { |
430 | } | 446 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
431 | Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 447 | } |
432 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 448 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
433 | let field = FieldId { parent: s.into(), local_id }; | 449 | self.db.struct_data(*s).variant_data.field(name).map(|local_id| { |
434 | self.write_field_resolution(tgt_expr, field); | 450 | let field = FieldId { parent: (*s).into(), local_id }; |
435 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) | 451 | self.write_field_resolution(tgt_expr, field); |
436 | }) | 452 | self.db.field_types((*s).into())[field.local_id] |
437 | } | 453 | .clone() |
438 | Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { | 454 | .subst(¶meters) |
439 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 455 | }) |
440 | let field = FieldId { parent: u.into(), local_id }; | 456 | } |
441 | self.write_field_resolution(tgt_expr, field); | 457 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { |
442 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) | 458 | self.db.union_data(*u).variant_data.field(name).map(|local_id| { |
443 | }) | 459 | let field = FieldId { parent: (*u).into(), local_id }; |
460 | self.write_field_resolution(tgt_expr, field); | ||
461 | self.db.field_types((*u).into())[field.local_id] | ||
462 | .clone() | ||
463 | .subst(¶meters) | ||
464 | }) | ||
465 | } | ||
466 | _ => None, | ||
444 | } | 467 | } |
445 | _ => None, | ||
446 | }) | 468 | }) |
447 | .unwrap_or(Ty::Unknown); | 469 | .unwrap_or(self.err_ty()); |
448 | let ty = self.insert_type_vars(ty); | 470 | let ty = self.insert_type_vars(ty); |
449 | self.normalize_associated_types_in(ty) | 471 | self.normalize_associated_types_in(ty) |
450 | } | 472 | } |
@@ -481,9 +503,10 @@ impl<'a> InferenceContext<'a> { | |||
481 | }; | 503 | }; |
482 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 504 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
483 | match rawness { | 505 | match rawness { |
484 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), | 506 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), |
485 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), | 507 | Rawness::Ref => TyKind::Ref(mutability, inner_ty), |
486 | } | 508 | } |
509 | .intern(&Interner) | ||
487 | } | 510 | } |
488 | Expr::Box { expr } => { | 511 | Expr::Box { expr } => { |
489 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 512 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
@@ -499,7 +522,7 @@ impl<'a> InferenceContext<'a> { | |||
499 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 522 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
500 | Ty::adt_ty(box_, sb.build()) | 523 | Ty::adt_ty(box_, sb.build()) |
501 | } else { | 524 | } else { |
502 | Ty::Unknown | 525 | self.err_ty() |
503 | } | 526 | } |
504 | } | 527 | } |
505 | Expr::UnaryOp { expr, op } => { | 528 | Expr::UnaryOp { expr, op } => { |
@@ -519,31 +542,31 @@ impl<'a> InferenceContext<'a> { | |||
519 | Some(derefed_ty) => { | 542 | Some(derefed_ty) => { |
520 | canonicalized.decanonicalize_ty(derefed_ty.value) | 543 | canonicalized.decanonicalize_ty(derefed_ty.value) |
521 | } | 544 | } |
522 | None => Ty::Unknown, | 545 | None => self.err_ty(), |
523 | } | 546 | } |
524 | } | 547 | } |
525 | None => Ty::Unknown, | 548 | None => self.err_ty(), |
526 | }, | 549 | }, |
527 | UnaryOp::Neg => { | 550 | UnaryOp::Neg => { |
528 | match &inner_ty { | 551 | match inner_ty.interned(&Interner) { |
529 | // Fast path for builtins | 552 | // Fast path for builtins |
530 | Ty::Scalar(Scalar::Int(_)) | 553 | TyKind::Scalar(Scalar::Int(_)) |
531 | | Ty::Scalar(Scalar::Uint(_)) | 554 | | TyKind::Scalar(Scalar::Uint(_)) |
532 | | Ty::Scalar(Scalar::Float(_)) | 555 | | TyKind::Scalar(Scalar::Float(_)) |
533 | | Ty::InferenceVar(_, TyVariableKind::Integer) | 556 | | TyKind::InferenceVar(_, TyVariableKind::Integer) |
534 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, | 557 | | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
535 | // Otherwise we resolve via the std::ops::Neg trait | 558 | // Otherwise we resolve via the std::ops::Neg trait |
536 | _ => self | 559 | _ => self |
537 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 560 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
538 | } | 561 | } |
539 | } | 562 | } |
540 | UnaryOp::Not => { | 563 | UnaryOp::Not => { |
541 | match &inner_ty { | 564 | match inner_ty.interned(&Interner) { |
542 | // Fast path for builtins | 565 | // Fast path for builtins |
543 | Ty::Scalar(Scalar::Bool) | 566 | TyKind::Scalar(Scalar::Bool) |
544 | | Ty::Scalar(Scalar::Int(_)) | 567 | | TyKind::Scalar(Scalar::Int(_)) |
545 | | Ty::Scalar(Scalar::Uint(_)) | 568 | | TyKind::Scalar(Scalar::Uint(_)) |
546 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | 569 | | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty, |
547 | // Otherwise we resolve via the std::ops::Not trait | 570 | // Otherwise we resolve via the std::ops::Not trait |
548 | _ => self | 571 | _ => self |
549 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 572 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -554,7 +577,9 @@ impl<'a> InferenceContext<'a> { | |||
554 | Expr::BinaryOp { lhs, rhs, op } => match op { | 577 | Expr::BinaryOp { lhs, rhs, op } => match op { |
555 | Some(op) => { | 578 | Some(op) => { |
556 | let lhs_expectation = match op { | 579 | let lhs_expectation = match op { |
557 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 580 | BinaryOp::LogicOp(..) => { |
581 | Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)) | ||
582 | } | ||
558 | _ => Expectation::none(), | 583 | _ => Expectation::none(), |
559 | }; | 584 | }; |
560 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 585 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -563,7 +588,7 @@ impl<'a> InferenceContext<'a> { | |||
563 | 588 | ||
564 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); | 589 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); |
565 | 590 | ||
566 | if ret == Ty::Unknown { | 591 | if ret.is_unknown() { |
567 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); | 592 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); |
568 | 593 | ||
569 | self.resolve_associated_type_with_params( | 594 | self.resolve_associated_type_with_params( |
@@ -575,7 +600,7 @@ impl<'a> InferenceContext<'a> { | |||
575 | ret | 600 | ret |
576 | } | 601 | } |
577 | } | 602 | } |
578 | _ => Ty::Unknown, | 603 | _ => self.err_ty(), |
579 | }, | 604 | }, |
580 | Expr::Range { lhs, rhs, range_type } => { | 605 | Expr::Range { lhs, rhs, range_type } => { |
581 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); | 606 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); |
@@ -586,33 +611,33 @@ impl<'a> InferenceContext<'a> { | |||
586 | match (range_type, lhs_ty, rhs_ty) { | 611 | match (range_type, lhs_ty, rhs_ty) { |
587 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 612 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
588 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), | 613 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), |
589 | None => Ty::Unknown, | 614 | None => self.err_ty(), |
590 | }, | 615 | }, |
591 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 616 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
592 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 617 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
593 | None => Ty::Unknown, | 618 | None => self.err_ty(), |
594 | }, | 619 | }, |
595 | (RangeOp::Inclusive, None, Some(ty)) => { | 620 | (RangeOp::Inclusive, None, Some(ty)) => { |
596 | match self.resolve_range_to_inclusive() { | 621 | match self.resolve_range_to_inclusive() { |
597 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 622 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
598 | None => Ty::Unknown, | 623 | None => self.err_ty(), |
599 | } | 624 | } |
600 | } | 625 | } |
601 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 626 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
602 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 627 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
603 | None => Ty::Unknown, | 628 | None => self.err_ty(), |
604 | }, | 629 | }, |
605 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 630 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
606 | match self.resolve_range_inclusive() { | 631 | match self.resolve_range_inclusive() { |
607 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 632 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
608 | None => Ty::Unknown, | 633 | None => self.err_ty(), |
609 | } | 634 | } |
610 | } | 635 | } |
611 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 636 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
612 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 637 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
613 | None => Ty::Unknown, | 638 | None => self.err_ty(), |
614 | }, | 639 | }, |
615 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 640 | (RangeOp::Inclusive, _, None) => self.err_ty(), |
616 | } | 641 | } |
617 | } | 642 | } |
618 | Expr::Index { base, index } => { | 643 | Expr::Index { base, index } => { |
@@ -631,19 +656,19 @@ impl<'a> InferenceContext<'a> { | |||
631 | index_trait, | 656 | index_trait, |
632 | ); | 657 | ); |
633 | let self_ty = | 658 | let self_ty = |
634 | self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); | 659 | self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value)); |
635 | self.resolve_associated_type_with_params( | 660 | self.resolve_associated_type_with_params( |
636 | self_ty, | 661 | self_ty, |
637 | self.resolve_ops_index_output(), | 662 | self.resolve_ops_index_output(), |
638 | &[index_ty], | 663 | &[index_ty], |
639 | ) | 664 | ) |
640 | } else { | 665 | } else { |
641 | Ty::Unknown | 666 | self.err_ty() |
642 | } | 667 | } |
643 | } | 668 | } |
644 | Expr::Tuple { exprs } => { | 669 | Expr::Tuple { exprs } => { |
645 | let mut tys = match &expected.ty { | 670 | let mut tys = match expected.ty.interned(&Interner) { |
646 | Ty::Tuple(_, substs) => substs | 671 | TyKind::Tuple(_, substs) => substs |
647 | .iter() | 672 | .iter() |
648 | .cloned() | 673 | .cloned() |
649 | .chain(repeat_with(|| self.table.new_type_var())) | 674 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -656,11 +681,11 @@ impl<'a> InferenceContext<'a> { | |||
656 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 681 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
657 | } | 682 | } |
658 | 683 | ||
659 | Ty::Tuple(tys.len(), Substs(tys.into())) | 684 | TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner) |
660 | } | 685 | } |
661 | Expr::Array(array) => { | 686 | Expr::Array(array) => { |
662 | let elem_ty = match &expected.ty { | 687 | let elem_ty = match expected.ty.interned(&Interner) { |
663 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), | 688 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), |
664 | _ => self.table.new_type_var(), | 689 | _ => self.table.new_type_var(), |
665 | }; | 690 | }; |
666 | 691 | ||
@@ -677,43 +702,50 @@ impl<'a> InferenceContext<'a> { | |||
677 | ); | 702 | ); |
678 | self.infer_expr( | 703 | self.infer_expr( |
679 | *repeat, | 704 | *repeat, |
680 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), | 705 | &Expectation::has_type( |
706 | TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), | ||
707 | ), | ||
681 | ); | 708 | ); |
682 | } | 709 | } |
683 | } | 710 | } |
684 | 711 | ||
685 | Ty::Array(Substs::single(elem_ty)) | 712 | TyKind::Array(elem_ty).intern(&Interner) |
686 | } | 713 | } |
687 | Expr::Literal(lit) => match lit { | 714 | Expr::Literal(lit) => match lit { |
688 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), | 715 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
689 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), | 716 | Literal::String(..) => { |
717 | TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) | ||
718 | } | ||
690 | Literal::ByteString(..) => { | 719 | Literal::ByteString(..) => { |
691 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); | 720 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
692 | let array_type = Ty::Array(Substs::single(byte_type)); | 721 | let array_type = TyKind::Array(byte_type).intern(&Interner); |
693 | Ty::Ref(Mutability::Not, Substs::single(array_type)) | 722 | TyKind::Ref(Mutability::Not, array_type).intern(&Interner) |
694 | } | 723 | } |
695 | Literal::Char(..) => Ty::Scalar(Scalar::Char), | 724 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
696 | Literal::Int(_v, ty) => match ty { | 725 | Literal::Int(_v, ty) => match ty { |
697 | Some(int_ty) => { | 726 | Some(int_ty) => { |
698 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | 727 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
728 | .intern(&Interner) | ||
699 | } | 729 | } |
700 | None => self.table.new_integer_var(), | 730 | None => self.table.new_integer_var(), |
701 | }, | 731 | }, |
702 | Literal::Uint(_v, ty) => match ty { | 732 | Literal::Uint(_v, ty) => match ty { |
703 | Some(int_ty) => { | 733 | Some(int_ty) => { |
704 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | 734 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
735 | .intern(&Interner) | ||
705 | } | 736 | } |
706 | None => self.table.new_integer_var(), | 737 | None => self.table.new_integer_var(), |
707 | }, | 738 | }, |
708 | Literal::Float(_v, ty) => match ty { | 739 | Literal::Float(_v, ty) => match ty { |
709 | Some(float_ty) => { | 740 | Some(float_ty) => { |
710 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | 741 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
742 | .intern(&Interner) | ||
711 | } | 743 | } |
712 | None => self.table.new_float_var(), | 744 | None => self.table.new_float_var(), |
713 | }, | 745 | }, |
714 | }, | 746 | }, |
715 | }; | 747 | }; |
716 | // use a new type variable if we got Ty::Unknown here | 748 | // use a new type variable if we got unknown here |
717 | let ty = self.insert_type_vars_shallow(ty); | 749 | let ty = self.insert_type_vars_shallow(ty); |
718 | let ty = self.resolve_ty_as_possible(ty); | 750 | let ty = self.resolve_ty_as_possible(ty); |
719 | self.write_expr_ty(tgt_expr, ty.clone()); | 751 | self.write_expr_ty(tgt_expr, ty.clone()); |
@@ -730,7 +762,7 @@ impl<'a> InferenceContext<'a> { | |||
730 | match stmt { | 762 | match stmt { |
731 | Statement::Let { pat, type_ref, initializer } => { | 763 | Statement::Let { pat, type_ref, initializer } => { |
732 | let decl_ty = | 764 | let decl_ty = |
733 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); | 765 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty()); |
734 | 766 | ||
735 | // Always use the declared type when specified | 767 | // Always use the declared type when specified |
736 | let mut ty = decl_ty.clone(); | 768 | let mut ty = decl_ty.clone(); |
@@ -738,7 +770,7 @@ impl<'a> InferenceContext<'a> { | |||
738 | if let Some(expr) = initializer { | 770 | if let Some(expr) = initializer { |
739 | let actual_ty = | 771 | let actual_ty = |
740 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | 772 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); |
741 | if decl_ty == Ty::Unknown { | 773 | if decl_ty.is_unknown() { |
742 | ty = actual_ty; | 774 | ty = actual_ty; |
743 | } | 775 | } |
744 | } | 776 | } |
@@ -766,7 +798,7 @@ impl<'a> InferenceContext<'a> { | |||
766 | // we don't even make an attempt at coercion | 798 | // we don't even make an attempt at coercion |
767 | self.table.new_maybe_never_var() | 799 | self.table.new_maybe_never_var() |
768 | } else { | 800 | } else { |
769 | self.coerce(&Ty::unit(), expected.coercion_target()); | 801 | self.coerce(&Ty::unit(), &expected.coercion_target()); |
770 | Ty::unit() | 802 | Ty::unit() |
771 | } | 803 | } |
772 | }; | 804 | }; |
@@ -802,7 +834,7 @@ impl<'a> InferenceContext<'a> { | |||
802 | self.write_method_resolution(tgt_expr, func); | 834 | self.write_method_resolution(tgt_expr, func); |
803 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 835 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
804 | } | 836 | } |
805 | None => (receiver_ty, Binders::new(0, Ty::Unknown), None), | 837 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), |
806 | }; | 838 | }; |
807 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 839 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
808 | let method_ty = method_ty.subst(&substs); | 840 | let method_ty = method_ty.subst(&substs); |
@@ -813,15 +845,15 @@ impl<'a> InferenceContext<'a> { | |||
813 | if !sig.params().is_empty() { | 845 | if !sig.params().is_empty() { |
814 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) | 846 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) |
815 | } else { | 847 | } else { |
816 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | 848 | (self.err_ty(), Vec::new(), sig.ret().clone()) |
817 | } | 849 | } |
818 | } | 850 | } |
819 | None => (Ty::Unknown, Vec::new(), Ty::Unknown), | 851 | None => (self.err_ty(), Vec::new(), self.err_ty()), |
820 | }; | 852 | }; |
821 | // Apply autoref so the below unification works correctly | 853 | // Apply autoref so the below unification works correctly |
822 | // FIXME: return correct autorefs from lookup_method | 854 | // FIXME: return correct autorefs from lookup_method |
823 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 855 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
824 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), | 856 | Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), |
825 | _ => derefed_receiver_ty, | 857 | _ => derefed_receiver_ty, |
826 | }; | 858 | }; |
827 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 859 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -837,7 +869,7 @@ impl<'a> InferenceContext<'a> { | |||
837 | // that we have more information about the types of arguments when we | 869 | // that we have more information about the types of arguments when we |
838 | // type-check the functions. This isn't really the right way to do this. | 870 | // type-check the functions. This isn't really the right way to do this. |
839 | for &check_closures in &[false, true] { | 871 | for &check_closures in &[false, true] { |
840 | let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); | 872 | let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty())); |
841 | for (&arg, param_ty) in args.iter().zip(param_iter) { | 873 | for (&arg, param_ty) in args.iter().zip(param_iter) { |
842 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); | 874 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); |
843 | if is_closure != check_closures { | 875 | if is_closure != check_closures { |
@@ -867,7 +899,7 @@ impl<'a> InferenceContext<'a> { | |||
867 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { | 899 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { |
868 | substs.push(receiver_ty.clone()); | 900 | substs.push(receiver_ty.clone()); |
869 | } else { | 901 | } else { |
870 | substs.push(Ty::Unknown); | 902 | substs.push(self.err_ty()); |
871 | } | 903 | } |
872 | } | 904 | } |
873 | } | 905 | } |
@@ -891,14 +923,15 @@ impl<'a> InferenceContext<'a> { | |||
891 | }; | 923 | }; |
892 | let supplied_params = substs.len(); |