aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/display.rs2
-rw-r--r--crates/hir/src/lib.rs132
-rw-r--r--crates/hir_ty/src/autoderef.rs24
-rw-r--r--crates/hir_ty/src/infer.rs2
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs16
-rw-r--r--crates/hir_ty/src/infer/unify.rs7
-rw-r--r--crates/hir_ty/src/method_resolution.rs6
-rw-r--r--crates/hir_ty/src/traits.rs17
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs5
10 files changed, 94 insertions, 123 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 9f6d7be48..97a78ca25 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -217,7 +217,7 @@ impl HirDisplay for Variant {
217 217
218impl HirDisplay for Type { 218impl HirDisplay for Type {
219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
220 self.ty.value.hir_fmt(f) 220 self.ty.hir_fmt(f)
221 } 221 }
222} 222}
223 223
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index b7ab03edf..30b96d7e2 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -58,7 +58,7 @@ use hir_ty::{
58 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, 59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
60 DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, 60 DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar,
61 Substitution, Ty, TyDefId, TyKind, TyVariableKind, WhereClause, 61 Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause,
62}; 62};
63use itertools::Itertools; 63use itertools::Itertools;
64use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -851,13 +851,7 @@ impl Function {
851 .iter() 851 .iter()
852 .enumerate() 852 .enumerate()
853 .map(|(idx, type_ref)| { 853 .map(|(idx, type_ref)| {
854 let ty = Type { 854 let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
855 krate,
856 ty: InEnvironment {
857 value: ctx.lower_ty(type_ref),
858 environment: environment.clone(),
859 },
860 };
861 Param { func: self, ty, idx } 855 Param { func: self, ty, idx }
862 }) 856 })
863 .collect() 857 .collect()
@@ -1540,8 +1534,8 @@ impl Impl {
1540 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1534 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1541 } 1535 }
1542 1536
1543 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { 1537 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
1544 let def_crates = match ty.value.def_crates(db, krate) { 1538 let def_crates = match ty.def_crates(db, krate) {
1545 Some(def_crates) => def_crates, 1539 Some(def_crates) => def_crates,
1546 None => return Vec::new(), 1540 None => return Vec::new(),
1547 }; 1541 };
@@ -1549,14 +1543,14 @@ impl Impl {
1549 let filter = |impl_def: &Impl| { 1543 let filter = |impl_def: &Impl| {
1550 let target_ty = impl_def.target_ty(db); 1544 let target_ty = impl_def.target_ty(db);
1551 let rref = target_ty.remove_ref(); 1545 let rref = target_ty.remove_ref();
1552 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) 1546 ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty))
1553 }; 1547 };
1554 1548
1555 let mut all = Vec::new(); 1549 let mut all = Vec::new();
1556 def_crates.iter().for_each(|&id| { 1550 def_crates.iter().for_each(|&id| {
1557 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) 1551 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1558 }); 1552 });
1559 let fp = TyFingerprint::for_impl(&ty.value); 1553 let fp = TyFingerprint::for_impl(&ty);
1560 for id in def_crates 1554 for id in def_crates
1561 .iter() 1555 .iter()
1562 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) 1556 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
@@ -1643,7 +1637,8 @@ impl Impl {
1643#[derive(Clone, PartialEq, Eq, Debug)] 1637#[derive(Clone, PartialEq, Eq, Debug)]
1644pub struct Type { 1638pub struct Type {
1645 krate: CrateId, 1639 krate: CrateId,
1646 ty: InEnvironment<Ty>, 1640 env: Arc<TraitEnvironment>,
1641 ty: Ty,
1647} 1642}
1648 1643
1649impl Type { 1644impl Type {
@@ -1663,14 +1658,14 @@ impl Type {
1663 ) -> Type { 1658 ) -> Type {
1664 let environment = 1659 let environment =
1665 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1660 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1666 Type { krate, ty: InEnvironment { value: ty, environment } } 1661 Type { krate, env: environment, ty }
1667 } 1662 }
1668 1663
1669 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { 1664 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1670 let resolver = lexical_env.resolver(db.upcast()); 1665 let resolver = lexical_env.resolver(db.upcast());
1671 let environment = 1666 let environment =
1672 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1667 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1673 Type { krate, ty: InEnvironment { value: ty, environment } } 1668 Type { krate, env: environment, ty }
1674 } 1669 }
1675 1670
1676 fn from_def( 1671 fn from_def(
@@ -1684,29 +1679,29 @@ impl Type {
1684 } 1679 }
1685 1680
1686 pub fn is_unit(&self) -> bool { 1681 pub fn is_unit(&self) -> bool {
1687 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) 1682 matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..))
1688 } 1683 }
1689 pub fn is_bool(&self) -> bool { 1684 pub fn is_bool(&self) -> bool {
1690 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) 1685 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1691 } 1686 }
1692 1687
1693 pub fn is_mutable_reference(&self) -> bool { 1688 pub fn is_mutable_reference(&self) -> bool {
1694 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) 1689 matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1695 } 1690 }
1696 1691
1697 pub fn is_usize(&self) -> bool { 1692 pub fn is_usize(&self) -> bool {
1698 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) 1693 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1699 } 1694 }
1700 1695
1701 pub fn remove_ref(&self) -> Option<Type> { 1696 pub fn remove_ref(&self) -> Option<Type> {
1702 match &self.ty.value.interned(&Interner) { 1697 match &self.ty.interned(&Interner) {
1703 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), 1698 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
1704 _ => None, 1699 _ => None,
1705 } 1700 }
1706 } 1701 }
1707 1702
1708 pub fn is_unknown(&self) -> bool { 1703 pub fn is_unknown(&self) -> bool {
1709 self.ty.value.is_unknown() 1704 self.ty.is_unknown()
1710 } 1705 }
1711 1706
1712 /// Checks that particular type `ty` implements `std::future::Future`. 1707 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1723,14 +1718,12 @@ impl Type {
1723 None => return false, 1718 None => return false,
1724 }; 1719 };
1725 1720
1726 let canonical_ty = Canonical { 1721 let canonical_ty =
1727 value: self.ty.value.clone(), 1722 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1728 binders: CanonicalVarKinds::empty(&Interner),
1729 };
1730 method_resolution::implements_trait( 1723 method_resolution::implements_trait(
1731 &canonical_ty, 1724 &canonical_ty,
1732 db, 1725 db,
1733 self.ty.environment.clone(), 1726 self.env.clone(),
1734 krate, 1727 krate,
1735 std_future_trait, 1728 std_future_trait,
1736 ) 1729 )
@@ -1748,14 +1741,12 @@ impl Type {
1748 None => return false, 1741 None => return false,
1749 }; 1742 };
1750 1743
1751 let canonical_ty = Canonical { 1744 let canonical_ty =
1752 value: self.ty.value.clone(), 1745 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1753 binders: CanonicalVarKinds::empty(&Interner),
1754 };
1755 method_resolution::implements_trait_unique( 1746 method_resolution::implements_trait_unique(
1756 &canonical_ty, 1747 &canonical_ty,
1757 db, 1748 db,
1758 self.ty.environment.clone(), 1749 self.env.clone(),
1759 krate, 1750 krate,
1760 fnonce_trait, 1751 fnonce_trait,
1761 ) 1752 )
@@ -1765,16 +1756,13 @@ impl Type {
1765 let trait_ref = hir_ty::TraitRef { 1756 let trait_ref = hir_ty::TraitRef {
1766 trait_id: hir_ty::to_chalk_trait_id(trait_.id), 1757 trait_id: hir_ty::to_chalk_trait_id(trait_.id),
1767 substitution: Substitution::build_for_def(db, trait_.id) 1758 substitution: Substitution::build_for_def(db, trait_.id)
1768 .push(self.ty.value.clone()) 1759 .push(self.ty.clone())
1769 .fill(args.iter().map(|t| t.ty.value.clone())) 1760 .fill(args.iter().map(|t| t.ty.clone()))
1770 .build(), 1761 .build(),
1771 }; 1762 };
1772 1763
1773 let goal = Canonical { 1764 let goal = Canonical {
1774 value: hir_ty::InEnvironment::new( 1765 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
1775 self.ty.environment.clone(),
1776 trait_ref.cast(&Interner),
1777 ),
1778 binders: CanonicalVarKinds::empty(&Interner), 1766 binders: CanonicalVarKinds::empty(&Interner),
1779 }; 1767 };
1780 1768
@@ -1789,12 +1777,12 @@ impl Type {
1789 alias: TypeAlias, 1777 alias: TypeAlias,
1790 ) -> Option<Type> { 1778 ) -> Option<Type> {
1791 let subst = Substitution::build_for_def(db, trait_.id) 1779 let subst = Substitution::build_for_def(db, trait_.id)
1792 .push(self.ty.value.clone()) 1780 .push(self.ty.clone())
1793 .fill(args.iter().map(|t| t.ty.value.clone())) 1781 .fill(args.iter().map(|t| t.ty.clone()))
1794 .build(); 1782 .build();
1795 let goal = Canonical::new( 1783 let goal = Canonical::new(
1796 InEnvironment::new( 1784 InEnvironment::new(
1797 self.ty.environment.clone(), 1785 self.env.env.clone(),
1798 AliasEq { 1786 AliasEq {
1799 alias: AliasTy::Projection(ProjectionTy { 1787 alias: AliasTy::Projection(ProjectionTy {
1800 associated_ty_id: to_assoc_type_id(alias.id), 1788 associated_ty_id: to_assoc_type_id(alias.id),
@@ -1826,22 +1814,22 @@ impl Type {
1826 } 1814 }
1827 1815
1828 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1816 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1829 let def = self.ty.value.callable_def(db); 1817 let def = self.ty.callable_def(db);
1830 1818
1831 let sig = self.ty.value.callable_sig(db)?; 1819 let sig = self.ty.callable_sig(db)?;
1832 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) 1820 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1833 } 1821 }
1834 1822
1835 pub fn is_closure(&self) -> bool { 1823 pub fn is_closure(&self) -> bool {
1836 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) 1824 matches!(&self.ty.interned(&Interner), TyKind::Closure { .. })
1837 } 1825 }
1838 1826
1839 pub fn is_fn(&self) -> bool { 1827 pub fn is_fn(&self) -> bool {
1840 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) 1828 matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1841 } 1829 }
1842 1830
1843 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1831 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1844 let adt_id = match self.ty.value.interned(&Interner) { 1832 let adt_id = match self.ty.interned(&Interner) {
1845 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1833 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1846 _ => return false, 1834 _ => return false,
1847 }; 1835 };
@@ -1854,11 +1842,11 @@ impl Type {
1854 } 1842 }
1855 1843
1856 pub fn is_raw_ptr(&self) -> bool { 1844 pub fn is_raw_ptr(&self) -> bool {
1857 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) 1845 matches!(&self.ty.interned(&Interner), TyKind::Raw(..))
1858 } 1846 }
1859 1847
1860 pub fn contains_unknown(&self) -> bool { 1848 pub fn contains_unknown(&self) -> bool {
1861 return go(&self.ty.value); 1849 return go(&self.ty);
1862 1850
1863 fn go(ty: &Ty) -> bool { 1851 fn go(ty: &Ty) -> bool {
1864 match ty.interned(&Interner) { 1852 match ty.interned(&Interner) {
@@ -1890,7 +1878,7 @@ impl Type {
1890 } 1878 }
1891 1879
1892 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1880 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1893 let (variant_id, substs) = match self.ty.value.interned(&Interner) { 1881 let (variant_id, substs) = match self.ty.interned(&Interner) {
1894 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1882 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1895 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1883 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1896 _ => return Vec::new(), 1884 _ => return Vec::new(),
@@ -1907,7 +1895,7 @@ impl Type {
1907 } 1895 }
1908 1896
1909 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1897 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1910 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { 1898 if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
1911 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1899 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1912 } else { 1900 } else {
1913 Vec::new() 1901 Vec::new()
@@ -1917,12 +1905,10 @@ impl Type {
1917 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1905 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1918 // There should be no inference vars in types passed here 1906 // There should be no inference vars in types passed here
1919 // FIXME check that? 1907 // FIXME check that?
1920 let canonical = Canonical { 1908 let canonical =
1921 value: self.ty.value.clone(), 1909 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1922 binders: CanonicalVarKinds::empty(&Interner), 1910 let environment = self.env.env.clone();
1923 }; 1911 let ty = InEnvironment { goal: canonical, environment };
1924 let environment = self.ty.environment.clone();
1925 let ty = InEnvironment { value: canonical, environment };
1926 autoderef(db, Some(self.krate), ty) 1912 autoderef(db, Some(self.krate), ty)
1927 .map(|canonical| canonical.value) 1913 .map(|canonical| canonical.value)
1928 .map(move |ty| self.derived(ty)) 1914 .map(move |ty| self.derived(ty))
@@ -1936,10 +1922,10 @@ impl Type {
1936 krate: Crate, 1922 krate: Crate,
1937 mut callback: impl FnMut(AssocItem) -> Option<T>, 1923 mut callback: impl FnMut(AssocItem) -> Option<T>,
1938 ) -> Option<T> { 1924 ) -> Option<T> {
1939 for krate in self.ty.value.def_crates(db, krate.id)? { 1925 for krate in self.ty.def_crates(db, krate.id)? {
1940 let impls = db.inherent_impls_in_crate(krate); 1926 let impls = db.inherent_impls_in_crate(krate);
1941 1927
1942 for impl_def in impls.for_self_ty(&self.ty.value) { 1928 for impl_def in impls.for_self_ty(&self.ty) {
1943 for &item in db.impl_data(*impl_def).items.iter() { 1929 for &item in db.impl_data(*impl_def).items.iter() {
1944 if let Some(result) = callback(item.into()) { 1930 if let Some(result) = callback(item.into()) {
1945 return Some(result); 1931 return Some(result);
@@ -1952,7 +1938,6 @@ impl Type {
1952 1938
1953 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1939 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1954 self.ty 1940 self.ty
1955 .value
1956 .strip_references() 1941 .strip_references()
1957 .substs() 1942 .substs()
1958 .into_iter() 1943 .into_iter()
@@ -1971,12 +1956,10 @@ impl Type {
1971 // There should be no inference vars in types passed here 1956 // There should be no inference vars in types passed here
1972 // FIXME check that? 1957 // FIXME check that?
1973 // FIXME replace Unknown by bound vars here 1958 // FIXME replace Unknown by bound vars here
1974 let canonical = Canonical { 1959 let canonical =
1975 value: self.ty.value.clone(), 1960 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1976 binders: CanonicalVarKinds::empty(&Interner),
1977 };
1978 1961
1979 let env = self.ty.environment.clone(); 1962 let env = self.env.clone();
1980 let krate = krate.id; 1963 let krate = krate.id;
1981 1964
1982 method_resolution::iterate_method_candidates( 1965 method_resolution::iterate_method_candidates(
@@ -2005,12 +1988,10 @@ impl Type {
2005 // There should be no inference vars in types passed here 1988 // There should be no inference vars in types passed here
2006 // FIXME check that? 1989 // FIXME check that?
2007 // FIXME replace Unknown by bound vars here 1990 // FIXME replace Unknown by bound vars here
2008 let canonical = Canonical { 1991 let canonical =
2009 value: self.ty.value.clone(), 1992 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
2010 binders: CanonicalVarKinds::empty(&Interner),
2011 };
2012 1993
2013 let env = self.ty.environment.clone(); 1994 let env = self.env.clone();
2014 let krate = krate.id; 1995 let krate = krate.id;
2015 1996
2016 method_resolution::iterate_method_candidates( 1997 method_resolution::iterate_method_candidates(
@@ -2026,16 +2007,16 @@ impl Type {
2026 } 2007 }
2027 2008
2028 pub fn as_adt(&self) -> Option<Adt> { 2009 pub fn as_adt(&self) -> Option<Adt> {
2029 let (adt, _subst) = self.ty.value.as_adt()?; 2010 let (adt, _subst) = self.ty.as_adt()?;
2030 Some(adt.into()) 2011 Some(adt.into())
2031 } 2012 }
2032 2013
2033 pub fn as_dyn_trait(&self) -> Option<Trait> { 2014 pub fn as_dyn_trait(&self) -> Option<Trait> {
2034 self.ty.value.dyn_trait().map(Into::into) 2015 self.ty.dyn_trait().map(Into::into)
2035 } 2016 }
2036 2017
2037 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2018 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2038 self.ty.value.impl_trait_bounds(db).map(|it| { 2019 self.ty.impl_trait_bounds(db).map(|it| {
2039 it.into_iter() 2020 it.into_iter()
2040 .filter_map(|pred| match pred.skip_binders() { 2021 .filter_map(|pred| match pred.skip_binders() {
2041 hir_ty::WhereClause::Implemented(trait_ref) => { 2022 hir_ty::WhereClause::Implemented(trait_ref) => {
@@ -2048,14 +2029,11 @@ impl Type {
2048 } 2029 }
2049 2030
2050 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> { 2031 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
2051 self.ty.value.associated_type_parent_trait(db).map(Into::into) 2032 self.ty.associated_type_parent_trait(db).map(Into::into)
2052 } 2033 }
2053 2034
2054 fn derived(&self, ty: Ty) -> Type { 2035 fn derived(&self, ty: Ty) -> Type {
2055 Type { 2036 Type { krate: self.krate, env: self.env.clone(), ty }
2056 krate: self.krate,
2057 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
2058 }
2059 } 2037 }
2060 2038
2061 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { 2039 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
@@ -2094,7 +2072,7 @@ impl Type {
2094 } 2072 }
2095 2073
2096 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2074 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
2097 let ty = type_.ty.value.strip_references(); 2075 let ty = type_.ty.strip_references();
2098 match ty.interned(&Interner) { 2076 match ty.interned(&Interner) {
2099 TyKind::Adt(..) => { 2077 TyKind::Adt(..) => {
2100 cb(type_.derived(ty.clone())); 2078 cb(type_.derived(ty.clone()));
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index d6f0553b1..dc5fc759a 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -27,9 +27,9 @@ pub fn autoderef<'a>(
27 krate: Option<CrateId>, 27 krate: Option<CrateId>,
28 ty: InEnvironment<Canonical<Ty>>, 28 ty: InEnvironment<Canonical<Ty>>,
29) -> impl Iterator<Item = Canonical<Ty>> + 'a { 29) -> impl Iterator<Item = Canonical<Ty>> + 'a {
30 let InEnvironment { value: ty, environment } = ty; 30 let InEnvironment { goal: ty, environment } = ty;
31 successors(Some(ty), move |ty| { 31 successors(Some(ty), move |ty| {
32 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) 32 deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
33 }) 33 })
34 .take(AUTODEREF_RECURSION_LIMIT) 34 .take(AUTODEREF_RECURSION_LIMIT)
35} 35}
@@ -39,8 +39,8 @@ pub(crate) fn deref(
39 krate: CrateId, 39 krate: CrateId,
40 ty: InEnvironment<&Canonical<Ty>>, 40 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 41) -> Option<Canonical<Ty>> {
42 if let Some(derefed) = ty.value.value.builtin_deref() { 42 if let Some(derefed) = ty.goal.value.builtin_deref() {
43 Some(Canonical { value: derefed, binders: ty.value.binders.clone() }) 43 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
44 } else { 44 } else {
45 deref_by_trait(db, krate, ty) 45 deref_by_trait(db, krate, ty)
46 } 46 }
@@ -67,15 +67,15 @@ fn deref_by_trait(
67 // FIXME make the Canonical / bound var handling nicer 67 // FIXME make the Canonical / bound var handling nicer
68 68
69 let parameters = 69 let parameters =
70 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
71 71
72 // Check that the type implements Deref at all 72 // Check that the type implements Deref at all
73 let trait_ref = 73 let trait_ref =
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; 74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
75 let implements_goal = Canonical { 75 let implements_goal = Canonical {
76 binders: ty.value.binders.clone(), 76 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 77 value: InEnvironment {
78 value: trait_ref.cast(&Interner), 78 goal: trait_ref.cast(&Interner),
79 environment: ty.environment.clone(), 79 environment: ty.environment.clone(),
80 }, 80 },
81 }; 81 };
@@ -91,20 +91,20 @@ fn deref_by_trait(
91 }), 91 }),
92 ty: TyKind::BoundVar(BoundVar::new( 92 ty: TyKind::BoundVar(BoundVar::new(
93 DebruijnIndex::INNERMOST, 93 DebruijnIndex::INNERMOST,
94 ty.value.binders.len(&Interner), 94 ty.goal.binders.len(&Interner),
95 )) 95 ))
96 .intern(&Interner), 96 .intern(&Interner),
97 }; 97 };
98 98
99 let obligation = projection.cast(&Interner); 99 let obligation = projection.cast(&Interner);
100 100
101 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
102 102
103 let canonical = Canonical { 103 let canonical = Canonical {
104 value: in_env, 104 value: in_env,
105 binders: CanonicalVarKinds::from_iter( 105 binders: CanonicalVarKinds::from_iter(
106 &Interner, 106 &Interner,
107 ty.value.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( 107 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
109 chalk_ir::UniverseIndex::ROOT, 109 chalk_ir::UniverseIndex::ROOT,
110 ))), 110 ))),
@@ -134,7 +134,7 @@ fn deref_by_trait(
134 if vars.0.value[i - 1].interned(&Interner) 134 if vars.0.value[i - 1].interned(&Interner)
135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
136 { 136 {
137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
138 return None; 138 return None;
139 } 139 }
140 } 140 }
@@ -144,7 +144,7 @@ fn deref_by_trait(
144 }) 144 })
145 } 145 }
146 Solution::Ambig(_) => { 146 Solution::Ambig(_) => {
147 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); 147 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
148 None 148 None
149 } 149 }
150 } 150 }
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index b9e434c78..8f9cf7480 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> {
331 fn resolve_obligations_as_possible(&mut self) { 331 fn resolve_obligations_as_possible(&mut self) {
332 let obligations = mem::replace(&mut self.obligations, Vec::new()); 332 let obligations = mem::replace(&mut self.obligations, Vec::new());
333 for obligation in obligations { 333 for obligation in obligations {
334 let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); 334 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
336 let solution = 336 let solution =
337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 07eb96573..9c62932b1 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -142,7 +142,7 @@ impl<'a> InferenceContext<'a> {
142 .build(); 142 .build();
143 let trait_ref = 143 let trait_ref =
144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; 144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
145 let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner)); 145 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
146 146
147 let canonicalizer = self.canonicalizer(); 147 let canonicalizer = self.canonicalizer();
148 let canonicalized = canonicalizer.canonicalize_obligation(goal); 148 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -170,8 +170,8 @@ impl<'a> InferenceContext<'a> {
170 self.db, 170 self.db,
171 self.resolver.krate(), 171 self.resolver.krate(),
172 InEnvironment { 172 InEnvironment {
173 value: canonicalized.value.clone(), 173 goal: canonicalized.value.clone(),
174 environment: self.trait_env.clone(), 174 environment: self.trait_env.env.clone(),
175 }, 175 },
176 ) { 176 ) {
177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 17849d552..4e2a432ed 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -90,12 +90,12 @@ impl<'a> InferenceContext<'a> {
90 let substs = 90 let substs =
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
92 92
93 let trait_env = Arc::clone(&self.trait_env); 93 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 94 let implements_fn_trait: DomainGoal =
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
96 .cast(&Interner); 96 .cast(&Interner);
97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
98 value: implements_fn_trait.clone(), 98 goal: implements_fn_trait.clone(),
99 environment: trait_env, 99 environment: trait_env,
100 }); 100 });
101 if self.db.trait_solve(krate, goal.value).is_some() { 101 if self.db.trait_solve(krate, goal.value).is_some() {
@@ -299,8 +299,8 @@ impl<'a> InferenceContext<'a> {
299 self.db, 299 self.db,
300 self.resolver.krate(), 300 self.resolver.krate(),
301 InEnvironment { 301 InEnvironment {
302 value: canonicalized.value.clone(), 302 goal: canonicalized.value.clone(),
303 environment: self.trait_env.clone(), 303 environment: self.trait_env.env.clone(),
304 }, 304 },
305 ); 305 );
306 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs 306 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs
@@ -438,8 +438,8 @@ impl<'a> InferenceContext<'a> {
438 self.db, 438 self.db,
439 self.resolver.krate(), 439 self.resolver.krate(),
440 InEnvironment { 440 InEnvironment {
441 value: canonicalized.value.clone(), 441 goal: canonicalized.value.clone(),
442 environment: self.trait_env.clone(), 442 environment: self.trait_env.env.clone(),
443 }, 443 },
444 ) 444 )
445 .find_map(|derefed_ty| { 445 .find_map(|derefed_ty| {
@@ -538,8 +538,8 @@ impl<'a> InferenceContext<'a> {
538 self.db, 538 self.db,
539 krate, 539 krate,
540 InEnvironment { 540 InEnvironment {
541 value: &canonicalized.value, 541 goal: &canonicalized.value,
542 environment: self.trait_env.clone(), 542 environment: self.trait_env.env.clone(),
543 }, 543 },
544 ) { 544 ) {
545 Some(derefed_ty) => { 545 Some(derefed_ty) => {
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 7595b46cf..75250a369 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -98,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
98 mut self, 98 mut self,
99 obligation: InEnvironment<DomainGoal>, 99 obligation: InEnvironment<DomainGoal>,
100 ) -> Canonicalized<InEnvironment<DomainGoal>> { 100 ) -> Canonicalized<InEnvironment<DomainGoal>> {
101 let result = match obligation.value { 101 let result = match obligation.goal {
102 DomainGoal::Holds(wc) => { 102 DomainGoal::Holds(wc) => {
103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) 103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
104 } 104 }
105 }; 105 };
106 self.into_canonicalized(InEnvironment { 106 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
107 value: result,
108 environment: obligation.environment,
109 })
110 } 107 }
111} 108}
112 109
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 0abe8f0a3..8e986ddde 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -376,7 +376,7 @@ fn iterate_method_candidates_impl(
376 // Also note that when we've got a receiver like &S, even if the method we 376 // Also note that when we've got a receiver like &S, even if the method we
377 // find in the end takes &self, we still do the autoderef step (just as 377 // find in the end takes &self, we still do the autoderef step (just as
378 // rustc does an autoderef and then autoref again). 378 // rustc does an autoderef and then autoref again).
379 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 379 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
380 380
381 // We have to be careful about the order we're looking at candidates 381 // We have to be careful about the order we're looking at candidates
382 // in here. Consider the case where we're resolving `x.clone()` 382 // in here. Consider the case where we're resolving `x.clone()`
@@ -622,7 +622,7 @@ pub fn resolve_indexing_op(
622 krate: CrateId, 622 krate: CrateId,
623 index_trait: TraitId, 623 index_trait: TraitId,
624) -> Option<Canonical<Ty>> { 624) -> Option<Canonical<Ty>> {
625 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 625 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
626 let deref_chain = autoderef_method_receiver(db, krate, ty); 626 let deref_chain = autoderef_method_receiver(db, krate, ty);
627 for ty in deref_chain { 627 for ty in deref_chain {
628 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); 628 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
@@ -794,7 +794,7 @@ fn generic_implements_goal(
794 let obligation = trait_ref.cast(&Interner); 794 let obligation = trait_ref.cast(&Interner);
795 Canonical { 795 Canonical {
796 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 796 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
797 value: InEnvironment::new(env, obligation), 797 value: InEnvironment::new(env.env.clone(), obligation),
798 } 798 }
799} 799}
800 800
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 7dadd1ffb..ccee0e5ad 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -1,6 +1,5 @@
1//! Trait solving using Chalk. 1//! Trait solving using Chalk.
2use std::env::var; 2use std::env::var;
3use std::sync::Arc;
4 3
5use base_db::CrateId; 4use base_db::CrateId;
6use chalk_ir::cast::Cast; 5use chalk_ir::cast::Cast;
@@ -44,7 +43,7 @@ pub struct TraitEnvironment {
44 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, 43 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord,
45 // but for now it's too annoying... 44 // but for now it's too annoying...
46 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, 45 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>,
47 pub(crate) env: chalk_ir::Environment<Interner>, 46 pub env: chalk_ir::Environment<Interner>,
48} 47}
49 48
50impl TraitEnvironment { 49impl TraitEnvironment {
@@ -74,13 +73,13 @@ impl Default for TraitEnvironment {
74/// Something (usually a goal), along with an environment. 73/// Something (usually a goal), along with an environment.
75#[derive(Clone, Debug, PartialEq, Eq, Hash)] 74#[derive(Clone, Debug, PartialEq, Eq, Hash)]
76pub struct InEnvironment<T> { 75pub struct InEnvironment<T> {
77 pub environment: Arc<TraitEnvironment>, 76 pub environment: chalk_ir::Environment<Interner>,
78 pub value: T, 77 pub goal: T,
79} 78}
80 79
81impl<T> InEnvironment<T> { 80impl<T> InEnvironment<T> {
82 pub fn new(environment: Arc<TraitEnvironment>, value: T) -> InEnvironment<T> { 81 pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
83 InEnvironment { environment, value } 82 InEnvironment { environment, goal: value }
84 } 83 }
85} 84}
86 85
@@ -126,18 +125,18 @@ pub(crate) fn trait_solve_query(
126 krate: CrateId, 125 krate: CrateId,
127 goal: Canonical<InEnvironment<DomainGoal>>, 126 goal: Canonical<InEnvironment<DomainGoal>>,
128) -> Option<Solution> { 127) -> Option<Solution> {
129 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { 128 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal {
130 DomainGoal::Holds(WhereClause::Implemented(it)) => { 129 DomainGoal::Holds(WhereClause::Implemented(it)) => {
131 db.trait_data(it.hir_trait_id()).name.to_string() 130 db.trait_data(it.hir_trait_id()).name.to_string()
132 } 131 }
133 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), 132 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
134 }); 133 });
135 log::info!("trait_solve_query({})", goal.value.value.display(db)); 134 log::info!("trait_solve_query({})", goal.value.goal.display(db));
136 135
137 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq { 136 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
138 alias: AliasTy::Projection(projection_ty), 137 alias: AliasTy::Projection(projection_ty),
139 .. 138 ..
140 })) = &goal.value.value 139 })) = &goal.value.goal
141 { 140 {
142 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 141 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
143 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 58d8f2894..aef6b8a15 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -455,10 +455,7 @@ where
455 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 455 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
456 456
457 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { 457 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
458 chalk_ir::InEnvironment { 458 chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
459 environment: self.environment.env.clone(),
460 goal: self.value.to_chalk(db),
461 }
462 } 459 }
463 460
464 fn from_chalk( 461 fn from_chalk(